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 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 &aEvent)
 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 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 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 std::string &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
 
const PCB_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
 
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 isInteractiveDragEnabled () const
 
bool isRouterActive () const
 
int doMoveSelection (TOOL_EVENT aEvent, bool aPickReference=false)
 
bool pickReferencePoint (const wxString &aTooltip, const wxString &aSuccessMessage, const wxString &aCanceledMessage, VECTOR2I &aReferencePoint)
 

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
 

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 111 of file pcb_tool_base.h.

111  {
113  IPO_ROTATE = 0x01,
114 
116  IPO_FLIP = 0x02,
117 
120  IPO_SINGLE_CLICK = 0x04,
121 
123  IPO_REPEAT = 0x08
124  };
Handle flip action in the loop by calling the item's flip method.
Allow repeat placement of the item.
Create an item immediately on placement starting, otherwise show the pencil cursor until the item is ...
Handle the rotate action in the loop by calling the item's rotate method.

◆ 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 78 of file tool_base.h.

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

Constructor & Destructor Documentation

◆ EDIT_TOOL()

EDIT_TOOL::EDIT_TOOL ( )

Definition at line 69 of file edit_tool.cpp.

69  :
70  PCB_TOOL_BASE( "pcbnew.InteractiveEdit" ),
72  m_dragging( false )
73 {
74 }
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
#define NULL
bool m_dragging
Definition: edit_tool.h:192
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
Definition: pcb_tool_base.h:78

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:215
TOOL_ID m_toolId
Name of the tool.
Definition: tool_base.h:210
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(), SYMBOL_EDITOR_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), SCH_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(), 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(), BOARD_INSPECTION_TOOL::HighlightNetTool(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), DRAWING_TOOL::InteractivePlaceWithPreview(), BOARD_INSPECTION_TOOL::LocalRatsnestTool(), PCB_PICKER_TOOL::Main(), PL_EDIT_TOOL::Main(), EE_POINT_EDITOR::Main(), SYMBOL_EDITOR_MOVE_TOOL::Main(), PL_POINT_EDITOR::Main(), SCH_MOVE_TOOL::Main(), PICKER_TOOL::Main(), ROUTER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::MainLoop(), GERBVIEW_INSPECTION_TOOL::MeasureTool(), PCB_VIEWER_TOOLS::MeasureTool(), LIB_TREE::onContextMenu(), PCB_POINT_EDITOR::OnSelectionChange(), GROUP_TOOL::PickNewMember(), SYMBOL_EDITOR_DRAWING_TOOLS::PlaceAnchor(), BOARD_EDITOR_CONTROL::PlaceFootprint(), SCH_DRAWING_TOOLS::PlaceImage(), DRAWING_TOOL::PlaceImportedGraphics(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), BOARD_EDITOR_CONTROL::PlaceTarget(), DRAWING_TOOL::PlaceText(), Remove(), POSITION_RELATIVE_TOOL::SelectPositionRelativeItem(), DRAWING_TOOL::SetAnchor(), DRC_TOOL::ShowDRCDialog(), SCH_DRAWING_TOOLS::SingleClickPlace(), SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace(), SCH_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 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215

References TOOL_BASE::m_toolMgr.

Referenced by TOOL_MANAGER::RegisterTool().

◆ board()

BOARD* PCB_TOOL_BASE::board ( ) const
inlineprotectedinherited

Definition at line 160 of file pcb_tool_base.h.

160 { return getModel<BOARD>(); }

Referenced by PCB_CONTROL::AppendBoard(), 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(), DragArcTrack(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), DRAWING_TOOL::drawSegment(), PAD_TOOL::EnumeratePads(), PAD_TOOL::explodePad(), BOARD_EDITOR_CONTROL::ExportNetlist(), ZONE_FILLER_TOOL::FillAllZones(), FilletTracks(), PCB_SELECTION_TOOL::filterSelection(), PCB_TOOL_BASE::footprint(), PCB_SELECTION_TOOL::GetBoard(), PCB_SELECTION_TOOL::getCollectorsGuide(), GROUP_TOOL::Group(), ROUTER_TOOL::handleLayerSwitch(), BOARD_INSPECTION_TOOL::highlightNet(), 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(), BOARD_EDITOR_CONTROL::PlaceTarget(), DRAWING_TOOL::PlaceText(), PCB_SELECTION_TOOL::RebuildSelection(), PAD_TOOL::recombinePad(), BOARD_EDITOR_CONTROL::RepairBoard(), PNS::TOOL_BASE::Reset(), PCB_CONTROL::Reset(), PCB_SELECTION_TOOL::Selectable(), PCB_SELECTION_TOOL::selectAllItemsOnNet(), PCB_SELECTION_TOOL::selectAllItemsOnSheet(), PCB_SELECTION_TOOL::selectConnectedTracks(), PCB_SELECTION_TOOL::selectionContains(), PCB_SELECTION_TOOL::selectPoint(), PCB_CONTROL::TrackDisplayMode(), GROUP_TOOL::Ungroup(), PCB_CONTROL::ViaDisplayMode(), PCB_CONTROL::ZoneDisplayMode(), ZONE_FILLER_TOOL::ZoneFill(), BOARD_EDITOR_CONTROL::ZoneMerge(), and ZONE_FILLER_TOOL::ZoneUnfillAll().

◆ canvas()

◆ ChangeTrackWidth()

int EDIT_TOOL::ChangeTrackWidth ( const TOOL_EVENT aEvent)

Definition at line 1039 of file edit_tool.cpp.

1040 {
1042  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1043  {
1044  // Iterate from the back so we don't have to worry about removals.
1045  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
1046  {
1047  BOARD_ITEM* item = aCollector[ i ];
1048 
1049  if( !dynamic_cast<TRACK*>( item ) )
1050  aCollector.Remove( item );
1051  }
1052  },
1053  true /* prompt user regarding locked items */ );
1054 
1055  for( EDA_ITEM* item : selection )
1056  {
1057  if( item->Type() == PCB_VIA_T )
1058  {
1059  VIA* via = static_cast<VIA*>( item );
1060 
1061  m_commit->Modify( via );
1062 
1063  int new_width;
1064  int new_drill;
1065 
1066  if( via->GetViaType() == VIATYPE::MICROVIA )
1067  {
1068  NETCLASS* netClass = via->GetNetClass();
1069 
1070  new_width = netClass->GetuViaDiameter();
1071  new_drill = netClass->GetuViaDrill();
1072  }
1073  else
1074  {
1075  new_width = board()->GetDesignSettings().GetCurrentViaSize();
1076  new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
1077  }
1078 
1079  via->SetDrill( new_drill );
1080  via->SetWidth( new_width );
1081  }
1082  else if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
1083  {
1084  TRACK* track = dynamic_cast<TRACK*>( item );
1085 
1086  wxCHECK( track, 0 );
1087 
1088  m_commit->Modify( track );
1089 
1090  int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
1091  track->SetWidth( new_width );
1092  }
1093  }
1094 
1095  m_commit->Push( _("Edit track width/via size") );
1096 
1097  if( selection.IsHover() )
1098  {
1100 
1101  // Notify other tools of the changes -- This updates the visual ratsnest
1103  }
1104 
1105  return 0;
1106 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
Definition: track.h:343
bool IsHover() const
Definition: selection.h:72
BOARD * board() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:593
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:206
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void SetWidth(int aWidth)
Definition: track.h:109
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
const PCB_SELECTION & selection() const
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:46
int GetuViaDiameter() const
Definition: netclass.h:140
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
The selection tool: currently supports:
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
int GetuViaDrill() const
Definition: netclass.h:144
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
Definition: track.h:83
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

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(), COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, 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 2380 of file edit_tool.cpp.

2381 {
2382  std::string tool = "pcbnew.InteractiveEdit.selectReferencePoint";
2383  CLIPBOARD_IO io;
2384  PCB_GRID_HELPER grid( m_toolMgr, getEditFrame<PCB_BASE_EDIT_FRAME>()->GetMagneticItemsSettings() );
2385 
2386  frame()->PushTool( tool );
2387  Activate();
2388 
2390  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2391  {
2392  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
2393  {
2394  BOARD_ITEM* item = aCollector[i];
2395 
2396  // We can't copy both a footprint and its text in the same operation, so if
2397  // both are selected, remove the text
2398  if( item->Type() == PCB_FP_TEXT_T && aCollector.HasItem( item->GetParent() ) )
2399  aCollector.Remove( item );
2400  }
2401  },
2402  aEvent.IsAction( &ACTIONS::cut ) && !m_isFootprintEditor /* prompt user regarding locked items */ );
2403 
2404  if( !selection.Empty() )
2405  {
2406  std::vector<BOARD_ITEM*> items;
2407 
2408  for( EDA_ITEM* item : selection )
2409  items.push_back( static_cast<BOARD_ITEM*>( item ) );
2410 
2411  VECTOR2I refPoint;
2412 
2413  if( aEvent.IsAction( &PCB_ACTIONS::copyWithReference ) )
2414  {
2415  if( !pickReferencePoint( _( "Select reference point for the copy..." ),
2416  _( "Selection copied" ),
2417  _( "Copy cancelled" ),
2418  refPoint ) )
2419  return 0;
2420  }
2421  else
2422  {
2423  refPoint = grid.BestDragOrigin( getViewControls()->GetCursorPosition(), items );
2424  }
2425 
2426  selection.SetReferencePoint( refPoint );
2427 
2428  io.SetBoard( board() );
2430  frame()->SetStatusText( _( "Selection copied" ) );
2431  }
2432 
2433  frame()->PopTool( tool );
2434 
2435  return 0;
2436 }
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
BOARD * board() const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
void SetBoard(BOARD *aBoard)
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
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:70
bool pickReferencePoint(const wxString &aTooltip, const wxString &aSuccessMessage, const wxString &aCanceledMessage, VECTOR2I &aReferencePoint)
Definition: edit_tool.cpp:2302
PCB_BASE_EDIT_FRAME * frame() const
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:264
const PCB_SELECTION & selection() const
virtual void PopTool(const std::string &actionName)
static TOOL_ACTION cut
Definition: actions.h:69
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
Definition: collector.h:203
static TOOL_ACTION copyWithReference
copy command with manual reference point selection
Definition: pcb_actions.h:102
bool m_isFootprintEditor
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
The selection tool: currently supports:
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
void Activate()
Run the tool.
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
void SaveSelection(const PCB_SELECTION &selected, bool isFootprintEditor)
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

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

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 2205 of file edit_tool.cpp.

2206 {
2207  if( isRouterActive() )
2208  {
2209  wxBell();
2210  return 0;
2211  }
2212 
2213  // Be sure that there is at least one item that we can modify
2215  []( const VECTOR2I&, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2216  {
2217  std::set<BOARD_ITEM*> added_items;
2218 
2219  // Iterate from the back so we don't have to worry about removals.
2220  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
2221  {
2222  BOARD_ITEM* item = aCollector[i];
2223 
2224  // We don't operate on pads; convert them to footprint selections
2225  if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T
2226  && !item->GetParent()->IsLocked() )
2227  {
2228  aCollector.Remove( item );
2229 
2230  if( item->GetParent() && !aCollector.HasItem( item->GetParent() ) )
2231  added_items.insert( item->GetParent() );
2232  }
2233  }
2234 
2235  for( BOARD_ITEM* item : added_items )
2236  aCollector.Append( item );
2237 
2238  sTool->FilterCollectorForGroups( aCollector );
2239  } );
2240 
2241  if( selection.Empty() )
2242  return 0;
2243 
2244  // we have a selection to work on now, so start the tool process
2245  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
2246  ARRAY_CREATOR array_creator( *editFrame, m_isFootprintEditor, selection );
2247  array_creator.Invoke();
2248 
2249  return 0;
2250 }
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:105
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
const PCB_SELECTION & selection() const
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
Definition: collector.h:203
bool m_isFootprintEditor
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
virtual bool IsLocked() const
Definition: board_item.h:249
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
bool isRouterActive() const
Definition: edit_tool.cpp:236
The selection tool: currently supports:
bool IsFootprintEditor() const
void FilterCollectorForGroups(GENERAL_COLLECTOR &aCollector) const
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References COLLECTOR::Append(), SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForGroups(), COLLECTOR::GetCount(), BOARD_ITEM::GetParent(), COLLECTOR::HasItem(), ARRAY_CREATOR::Invoke(), PCB_TOOL_BASE::IsFootprintEditor(), BOARD_ITEM::IsLocked(), isRouterActive(), PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, PCB_PAD_T, COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), PCB_TOOL_BASE::selection(), and EDA_ITEM::Type().

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 2439 of file edit_tool.cpp.

2440 {
2441  if( !copyToClipboard( aEvent ) )
2442  {
2443  // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items
2444  // that were copied to the clipboard, no more, no fewer. Filtering for locked item, if
2445  // any will be done in the copyToClipboard() routine
2446  TOOL_EVENT evt( aEvent.Category(), aEvent.Action(), TOOL_ACTION_SCOPE::AS_GLOBAL );
2448  Remove( evt );
2449  }
2450 
2451  return 0;
2452 }
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:251
TOOL_EVENT_CATEGORY Category() const
Returns more specific information about the type of an event.
Definition: tool_event.h:248
void SetParameter(T aParam)
Set a non-standard parameter assigned to the event.
Definition: tool_event.h:461
Generic, UI-independent tool event.
Definition: tool_event.h:173
Global action (toolbar/main menu event, global shortcut)
Definition: tool_event.h:151
int Remove(const TOOL_EVENT &aEvent)
Delete currently selected items.
Definition: edit_tool.cpp:1727
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:2380

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

Referenced by setTransitions().

◆ displayOptions()

const PCB_DISPLAY_OPTIONS & PCB_TOOL_BASE::displayOptions ( ) const
protectedinherited

Definition at line 290 of file pcb_tool_base.cpp.

291 {
292  return frame()->GetDisplayOptions();
293 }
const PCB_DISPLAY_OPTIONS & GetDisplayOptions() const
Display options control the way tracks, vias, outlines and other things are shown (for instance solid...
PCB_BASE_EDIT_FRAME * frame() const

References PCB_TOOL_BASE::frame(), and PCB_BASE_FRAME::GetDisplayOptions().

Referenced by BOARD_INSPECTION_TOOL::calculateSelectionRatsnest(), PCB_CONTROL::HighContrastMode(), PCB_CONTROL::HighContrastModeCycle(), BOARD_INSPECTION_TOOL::LocalRatsnestTool(), PNS::TOOL_BASE::pickSingleItem(), PCB_CONTROL::ToggleRatsnest(), PCB_CONTROL::TrackDisplayMode(), PCB_CONTROL::ViaDisplayMode(), and PCB_CONTROL::ZoneDisplayMode().

◆ doInteractiveItemPlacement()

void PCB_TOOL_BASE::doInteractiveItemPlacement ( const std::string &  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 35 of file pcb_tool_base.cpp.

38 {
39  using namespace std::placeholders;
40  std::unique_ptr<BOARD_ITEM> newItem;
41 
42  frame()->PushTool( aTool );
43  Activate();
44 
45  BOARD_COMMIT commit( frame() );
46 
48 
49  // do not capture or auto-pan until we start placing an item
50  controls()->ShowCursor( true );
51 
52  // Add a VIEW_GROUP that serves as a preview for the new item
53  PCB_SELECTION preview;
54  view()->Add( &preview );
55 
56  aPlacer->m_board = board();
57  aPlacer->m_frame = frame();
58  aPlacer->m_modifiers = 0;
59 
60  auto makeNewItem =
61  [&]( VECTOR2I aPosition )
62  {
63  if( frame()->GetModel() )
64  newItem = aPlacer->CreateItem();
65 
66  if( newItem )
67  {
68  newItem->SetPosition( (wxPoint) aPosition );
69  preview.Add( newItem.get() );
70 
71  if( newItem->Type() == PCB_FOOTPRINT_T )
72  {
73  FOOTPRINT* fp = dyn_cast<FOOTPRINT*>( newItem.get() );
74 
75  // footprints have more drawable parts
76  fp->RunOnChildren( std::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
77  }
78  }
79  };
80 
81  if( aOptions & IPO_SINGLE_CLICK )
82  makeNewItem( controls()->GetCursorPosition() );
83 
84  auto setCursor =
85  [&]()
86  {
87  if( !newItem )
89  else
91  };
92 
93  // Set initial cursor
94  setCursor();
95 
96  // Main loop: keep receiving events
97  while( TOOL_EVENT* evt = Wait() )
98  {
99  setCursor();
100 
101  VECTOR2I cursorPos = controls()->GetCursorPosition();
102  aPlacer->m_modifiers = evt->Modifier();
103 
104  auto cleanup =
105  [&] ()
106  {
107  newItem = nullptr;
108  preview.Clear();
109  view()->Update( &preview );
110  controls()->SetAutoPan( false );
111  controls()->CaptureCursor( false );
112  controls()->ShowCursor( true );
113  };
114 
115  if( evt->IsCancelInteractive() )
116  {
117  if( aOptions & IPO_SINGLE_CLICK )
118  {
119  cleanup();
120  frame()->PopTool( aTool );
121  break;
122  }
123  else if( newItem )
124  cleanup();
125  else
126  {
127  frame()->PopTool( aTool );
128  break;
129  }
130  }
131  else if( evt->IsActivate() )
132  {
133  if( newItem )
134  cleanup();
135 
136  if( evt->IsPointEditor() )
137  {
138  // don't exit (the point editor runs in the background)
139  }
140  else if( evt->IsMoveTool() )
141  {
142  // leave ourselves on the stack so we come back after the move
143  break;
144  }
145  else
146  {
147  frame()->PopTool( aTool );
148  break;
149  }
150  }
151  else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
152  {
153  if( !newItem )
154  {
155  // create the item if possible
156  makeNewItem( cursorPos );
157 
158  // no item created, so wait for another click
159  if( !newItem )
160  continue;
161 
162  controls()->CaptureCursor( true );
163  controls()->SetAutoPan( true );
164  }
165  else
166  {
167  auto oldFlags = newItem->GetFlags();
168  newItem->ClearFlags();
169 
170  if( !aPlacer->PlaceItem( newItem.get(), commit ) )
171  {
172  newItem->SetFlags( oldFlags );
173  continue;
174  }
175 
176  preview.Clear();
177  newItem.release();
178  commit.Push( aCommitMessage );
179 
180  controls()->CaptureCursor( false );
181  controls()->SetAutoPan( false );
182  controls()->ShowCursor( true );
183 
184  if( !( aOptions & IPO_REPEAT ) )
185  break;
186 
187  if( aOptions & IPO_SINGLE_CLICK )
188  makeNewItem( controls()->GetCursorPosition() );
189 
190  setCursor();
191  }
192  }
193  else if( evt->IsClick( BUT_RIGHT ) )
194  {
196  }
197  else if( evt->IsAction( &PCB_ACTIONS::trackViaSizeChanged ) )
198  {
200  }
201  else if( newItem && evt->Category() == TC_COMMAND )
202  {
203  /*
204  * Handle any events that can affect the item as we move it around
205  */
206  if( TOOL_EVT_UTILS::IsRotateToolEvt( *evt ) && ( aOptions & IPO_ROTATE ) )
207  {
208  const int rotationAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *frame(), *evt );
209  newItem->Rotate( newItem->GetPosition(), rotationAngle );
210  view()->Update( &preview );
211  }
212  else if( evt->IsAction( &PCB_ACTIONS::flip ) && ( aOptions & IPO_FLIP ) )
213  {
214  newItem->Flip( newItem->GetPosition(), frame()->Settings().m_FlipLeftRight );
215  view()->Update( &preview );
216  }
217  else if( evt->IsAction( &PCB_ACTIONS::viaSizeInc )
218  || evt->IsAction( &PCB_ACTIONS::viaSizeDec ) )
219  {
220  // Refresh preview after event runs
222  }
223  else if( evt->IsAction( &PCB_ACTIONS::properties ) )
224  {
225  frame()->OnEditItemRequest( newItem.get() );
226 
227  // Notify other tools of the changes
229  }
230  else if( evt->IsAction( &ACTIONS::refreshPreview ) )
231  {
232  preview.Clear();
233  newItem.release();
234 
235  makeNewItem( (wxPoint) cursorPos );
236  aPlacer->SnapItem( newItem.get() );
237  view()->Update( &preview );
238  }
239  else
240  {
241  evt->SetPassEvent();
242  }
243  }
244  else if( newItem && evt->IsMotion() )
245  {
246  // track the cursor
247  newItem->SetPosition( (wxPoint) cursorPos );
248  aPlacer->SnapItem( newItem.get() );
249 
250  // Show a preview of the item
251  view()->Update( &preview );
252  }
253  else
254  {
255  evt->SetPassEvent();
256  }
257  }
258 
259  view()->Remove( &preview );
261 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
virtual void Clear() override
Remove all the stored items from the group.
Definition: selection.h:96
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
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.
virtual bool PlaceItem(BOARD_ITEM *aItem, BOARD_COMMIT &aCommit)
Handle flip action in the loop by calling the item's flip method.
BOARD * board() const
static TOOL_ACTION viaSizeInc
Definition: pcb_actions.h:302
virtual std::unique_ptr< BOARD_ITEM > CreateItem()=0
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
virtual void OnEditItemRequest(BOARD_ITEM *aItem)=0
Install the corresponding dialog editor for the given item.
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:121
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
static TOOL_ACTION trackViaSizeChanged
Definition: pcb_actions.h:305
bool IsRotateToolEvt(const TOOL_EVENT &aEvt)
Function isRotateToolEvt()
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:75
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:206
virtual void Add(EDA_ITEM *aItem)
Definition: selection.h:77
TOOL_MANAGER * GetManager() const
Return the instance of TOOL_MANAGER that takes care of the tool.
Definition: tool_base.h:144
PCB_BASE_EDIT_FRAME * frame() const
virtual void SnapItem(BOARD_ITEM *aItem)
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
const PCB_SELECTION & selection() const
Allow repeat placement of the item.
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
virtual void PopTool(const std::string &actionName)
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
Generic, UI-independent tool event.
Definition: tool_event.h:173
KIGFX::PCB_VIEW * view() const
Create an item immediately on placement starting, otherwise show the pencil cursor until the item is ...
virtual void Add(VIEW_ITEM *aItem)
Add an item to the group.
Definition: view_group.cpp:56
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:109
Handle the rotate action in the loop by calling the item's rotate method.
KIGFX::VIEW_CONTROLS * controls() const
PCBNEW_SETTINGS & Settings()
void Activate()
Run the tool.
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:1175
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
Definition: pcb_view.cpp:58
PCB_BASE_EDIT_FRAME * m_frame
Definition: pcb_tool_base.h:65
int GetEventRotationAngle(const PCB_BASE_EDIT_FRAME &aFrame, const TOOL_EVENT &aEvt)
Function getEventRotationAngle()
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:59
static TOOL_ACTION viaSizeDec
Definition: pcb_actions.h:303
static TOOL_ACTION refreshPreview
Definition: actions.h:109
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.

References TOOL_INTERACTIVE::Activate(), KIGFX::PCB_VIEW::Add(), KIGFX::VIEW_GROUP::Add(), SELECTION::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, PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetCanvas(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), TOOL_EVT_UTILS::GetEventRotationAngle(), TOOL_BASE::GetManager(), PCB_BASE_FRAME::GetModel(), 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, PCBNEW_SETTINGS::m_FlipLeftRight, 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(), PCB_BASE_FRAME::Settings(), TOOL_MENU::ShowContextMenu(), KIGFX::VIEW_CONTROLS::ShowCursor(), INTERACTIVE_PLACER_BASE::SnapItem(), TC_COMMAND, PCB_ACTIONS::trackViaSizeChanged, KIGFX::PCB_VIEW::Update(), PCB_ACTIONS::viaSizeDec, PCB_ACTIONS::viaSizeInc, 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 ( TOOL_EVENT  aEvent,
bool  aPickReference = false 
)
private

Definition at line 655 of file edit_tool.cpp.

656 {
657  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
659  VECTOR2I originalCursorPos = controls->GetCursorPosition();
660 
661  // Be sure that there is at least one item that we can modify. If nothing was selected before,
662  // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
664  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
665  {
666  // Iterate from the back so we don't have to worry about removals.
667  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
668  {
669  BOARD_ITEM* item = aCollector[ i ];
670 
671  if( item->Type() == PCB_MARKER_T )
672  aCollector.Remove( item );
673  }
674  } );
675 
676  if( m_dragging || selection.Empty() )
677  return 0;
678 
679  LSET item_layers = selection.GetSelectionLayers();
680  bool is_hover = selection.IsHover(); // N.B. This must be saved before the re-selection
681  // below
682  VECTOR2I pickedReferencePoint;
683 
684  // Now filter out locked and grouped items. We cannot do this in the first RequestSelection()
685  // as we need the item_layers when a pad is the selection front.
686  if( frame()->Settings().m_AllowFreePads )
687  {
689  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
690  {
691  std::set<BOARD_ITEM*> to_add;
692 
693  // Iterate from the back so we don't have to worry about removals.
694  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
695  {
696  BOARD_ITEM* item = aCollector[i];
697 
698  if( item->Type() == PCB_MARKER_T )
699  aCollector.Remove( item );
700 
701  // Locked pads do not get moved independently of the footprint
702  if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T
703  && item->IsLocked() )
704  {
705  if( !aCollector.HasItem( item->GetParent() ) )
706  to_add.insert( item->GetParent() );
707 
708  aCollector.Remove( item );
709  }
710  }
711 
712  for( BOARD_ITEM* item : to_add )
713  aCollector.Append( item );
714  },
715  !m_isFootprintEditor /* prompt user regarding locked items only in pcb editor*/ );
716  }
717  else
718  {
719  // Unlocked pads are treated as locked if the setting m_AllowFreePads is false
721  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector,
722  PCB_SELECTION_TOOL* sTool )
723  {
724  std::set<BOARD_ITEM*> to_add;
725 
726  // Iterate from the back so we don't have to worry about removals.
727  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
728  {
729  BOARD_ITEM* item = aCollector[i];
730 
731  if( item->Type() == PCB_MARKER_T )
732  aCollector.Remove( item );
733 
734  // Treat all pads as locked (i.e. cannot be moved indepenendtly of footprint)
735  if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T )
736  {
737  if( !aCollector.HasItem( item->GetParent() ) )
738  to_add.insert( item->GetParent() );
739 
740  aCollector.Remove( item );
741  }
742  }
743 
744  for( BOARD_ITEM* item : to_add )
745  aCollector.Append( item );
746  },
747  !m_isFootprintEditor /* prompt user regarding locked items only in pcb editor*/ );
748  }
749 
750  if( selection.Empty() )
751  return 0;
752 
753  std::string tool = aEvent.GetCommandStr().get();
754  editFrame->PushTool( tool );
755  Activate();
756  controls->ShowCursor( true );
757  controls->SetAutoPan( true );
758 
759  if( aPickReference && !pickReferencePoint( _( "Select reference point for move..." ), "", "",
760  pickedReferencePoint ) )
761  {
762  if( is_hover )
764 
765  editFrame->PopTool( tool );
766  return 0;
767  }
768 
769  std::vector<BOARD_ITEM*> sel_items; // All the items operated on by the move below
770  std::vector<BOARD_ITEM*> orig_items; // All the original items in the selection
771 
772  for( EDA_ITEM* item : selection )
773  {
774  BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
775  FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item );
776 
777  if( boardItem )
778  {
779  orig_items.push_back( boardItem );
780  sel_items.push_back( boardItem );
781  }
782 
783  if( footprint )
784  {
785  for( PAD* pad : footprint->Pads() )
786  sel_items.push_back( pad );
787  }
788  }
789 
790  bool restore_state = false;
791  VECTOR2I totalMovement;
793  TOOL_EVENT* evt = &aEvent;
794  VECTOR2I prevPos;
795 
796  bool hasMouseMoved = false;
797 
798  // Prime the pump
800 
801  // Main loop: keep receiving events
802  do
803  {
804  VECTOR2I movement;
806  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
807  grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
808 
809  if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
810  hasMouseMoved = true;
811 
812  if( evt->IsAction( &PCB_ACTIONS::move ) || evt->IsMotion() || evt->IsDrag( BUT_LEFT )
813  || evt->IsAction( &ACTIONS::refreshPreview )
814  || evt->IsAction( &PCB_ACTIONS::moveWithReference ) )
815  {
816  if( m_dragging && evt->Category() == TC_MOUSE )
817  {
818  VECTOR2I mousePos( controls->GetMousePosition() );
819 
820  m_cursor = grid.BestSnapAnchor( mousePos, item_layers, sel_items );
821 
823  {
825 
826  // The arrow keys are by definition SINGLE AXIS. Do not allow the other
827  // axis to be snapped to the grid.
828  if( action == ACTIONS::CURSOR_LEFT || action == ACTIONS::CURSOR_RIGHT )
829  m_cursor.y = prevPos.y;
830  else if( action == ACTIONS::CURSOR_UP || action == ACTIONS::CURSOR_DOWN )
831  m_cursor.x = prevPos.x;
832  }
833 
836 
837  movement = m_cursor - prevPos;
838  prevPos = m_cursor;
839  totalMovement += movement;
840 
841  // Drag items to the current cursor position
842  for( EDA_ITEM* item : sel_items )
843  {
844  // Don't double move footprint pads, fields, etc.
845  //
846  // For PCB_GROUP_T, we make sure the selection includes only the top level
847  // group and not its descendants.
848  if( !item->GetParent() || !item->GetParent()->IsSelected() )
849  static_cast<BOARD_ITEM*>( item )->Move( movement );
850  }
851 
853  }
854  else if( !m_dragging && !evt->IsAction( &ACTIONS::refreshPreview ) )
855  {
856  // Prepare to start dragging
857  if( !( evt->IsAction( &PCB_ACTIONS::move )
858  || evt->IsAction( &PCB_ACTIONS::moveWithReference ) )
860  {
862  break;
863  }
864 
865  m_dragging = true;
866 
867  // When editing footprints, all items have the same parent
868  if( IsFootprintEditor() )
869  {
870  m_commit->Modify( selection.Front() );
871  }
872  else
873  {
874  // Save items, so changes can be undone
875  for( EDA_ITEM* item : selection )
876  {
877  // Don't double move footprint pads, fields, etc.
878  //
879  // For PCB_GROUP_T, the parent is the board.
880  if( item->GetParent() && item->GetParent()->IsSelected() )
881  continue;
882 
883  m_commit->Modify( item );
884 
885  // If moving a group, record position of all the descendants for undo
886  if( item->Type() == PCB_GROUP_T )
887  {
888  PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
889  group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
890  {
891  m_commit->Modify( bItem );
892  });
893  }
894  }
895  }
896 
897  editFrame->UndoRedoBlock( true );
899 
901  {
902  // start moving with the reference point attached to the cursor
903  grid.SetAuxAxes( false );
904 
905  movement = m_cursor - selection.GetReferencePoint();
906 
907  // Drag items to the current cursor position
908  for( EDA_ITEM* item : selection )
909  {
910  // Don't double move footprint pads, fields, etc.
911  if( item->GetParent() && item->GetParent()->IsSelected() )
912  continue;
913 
914  static_cast<BOARD_ITEM*>( item )->Move( movement );
915  }
916 
918  }
919  else
920  {
921  std::vector<BOARD_ITEM*> items;
922 
923  for( EDA_ITEM* item : selection )
924  items.push_back( static_cast<BOARD_ITEM*>( item ) );
925 
926  m_cursor = grid.BestDragOrigin( originalCursorPos, items );
927 
928  // Set the current cursor position to the first dragged item origin, so the
929  // movement vector could be computed later
930  if( aPickReference )
931  {
932  selection.SetReferencePoint( pickedReferencePoint );
933  controls->ForceCursorPosition( true, pickedReferencePoint );
934  m_cursor = pickedReferencePoint;
935  }
936  else
937  {
938  // Check if user wants to warp the mouse to origin of moved object
939  if( !editFrame->GetMoveWarpsCursor() )
940  m_cursor = originalCursorPos; // No, so use original mouse pos instead
941 
943  grid.SetAuxAxes( true, m_cursor );
944  }
945  }
946 
948 
949  prevPos = m_cursor;
950  controls->SetAutoPan( true );
952  }
953 
955  new VECTOR2I( movement ) );
956  }
957 
958  else if( evt->IsCancelInteractive() || evt->IsActivate() )
959  {
960  if( m_dragging && evt->IsCancelInteractive() )
961  evt->SetPassEvent( false );
962 
963  restore_state = true; // Canceling the tool means that items have to be restored
964  break; // Finish
965  }
966 
967  else if( evt->IsAction( &ACTIONS::undo ) )
968  {
969  restore_state = true; // Perform undo locally
970  break; // Finish
971  }
972 
973  // Dispatch TOOL_ACTIONs
974  else if( evt->IsAction( &ACTIONS::doDelete ) )
975  {
976  break; // finish -- there is no further processing for removed items
977  }
978  else if( evt->IsAction( &ACTIONS::duplicate ) )
979  {
980  break; // finish -- Duplicate tool will start a new Move with the dup'ed items
981  }
982  else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
983  {
984  // Reset positions so the Move Exactly is from the start.
985  for( EDA_ITEM* item : selection )
986  {
987  BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
988  i->Move( -totalMovement );
989  }
990 
991  break; // finish -- we moved exactly, so we are finished
992  }
993  else if( hasMouseMoved && ( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
994  {
995  // Ignore mouse up and click events until we receive at least one mouse move or
996  // mouse drag event
997  break; // finish
998  }
999  else
1000  {
1001  evt->SetPassEvent();
1002  }
1003 
1004  } while( ( evt = Wait() ) ); // Assignment (instead of equality test) is intentional
1005 
1006  controls->ForceCursorPosition( false );
1007  controls->ShowCursor( false );
1008  controls->SetAutoPan( false );
1009 
1010  m_dragging = false;
1011  editFrame->UndoRedoBlock( false );
1012 
1013  // Discard reference point when selection is "dropped" onto the board
1015 
1016  // TODO: there's an ecapsulation leak here: this commit often has more than just the move
1017  // in it; for instance it might have a paste, append board, etc. as well.
1018  if( restore_state )
1019  m_commit->Revert();
1020  else
1021  m_commit->Push( _( "Drag" ) );
1022 
1023  // Remove the dynamic ratsnest from the screen
1025 
1026  // Unselect all items to update flags
1028 
1029  // Reselect items if they were already selected and we completed the move
1030  if( !is_hover && !restore_state )
1031  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &orig_items );
1032 
1033  editFrame->PopTool( tool );
1034 
1035  return restore_state ? -1 : 0;
1036 }
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: pcb_actions.h:70
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
VECTOR2I GetReferencePoint() const
Definition: selection.h:259
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2I m_cursor
Definition: edit_tool.h:193
void ClearReferencePoint()
Definition: selection.h:269
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:96
bool IsHover() const
Definition: selection.h:72
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
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.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
bool IsSelected() const
Definition: eda_item.h:173
static TOOL_ACTION doDelete
Definition: actions.h:75
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:50
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
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.
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
void UndoRedoBlock(bool aBlock=true)
Enable/disable undo and redo operations.
virtual MAGNETIC_SETTINGS * GetMagneticItemsSettings()
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:206
PADS & Pads()
Definition: footprint.h:164
const VC_SETTINGS & GetSettings() const
Apply VIEW_CONTROLS settings from an object.
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:124
bool pickReferencePoint(const wxString &aTooltip, const wxString &aSuccessMessage, const wxString &aCanceledMessage, VECTOR2I &aReferencePoint)
Definition: edit_tool.cpp:2302
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:105
PCB_BASE_EDIT_FRAME * frame() const
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:264
bool isInteractiveDragEnabled() const
Definition: edit_tool.cpp:228
LSET is a set of PCB_LAYER_IDs.
const PCB_SELECTION & selection() const
bool m_dragging
Definition: edit_tool.h:192
virtual void Move(const wxPoint &aMoveVector)
Move this object.
Definition: board_item.h:277
virtual void PopTool(const std::string &actionName)
Generic, UI-independent tool event.
Definition: tool_event.h:173
FOOTPRINT * footprint() const
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
Definition: collector.h:203
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
static const TOOL_EVENT SelectedItemsMoved
Used to inform tools that the selection should temporarily be non-editable.
Definition: actions.h:209
bool m_isFootprintEditor
static TOOL_ACTION hideDynamicRatsnest
Definition: pcb_actions.h:459
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:471
virtual bool IsLocked() const
Definition: board_item.h:249
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:200
bool HasReferencePoint() const
Definition: selection.h:254
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:98
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
KIGFX::VIEW_CONTROLS * controls() const
Common, abstract interface for edit frames.
#define _(s)
Definition: 3d_actions.cpp:33
long m_lastKeyboardCursorCommand
Position of the above event.
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
bool m_lastKeyboardCursorPositionValid
ACTIONS::CURSOR_UP, ACTIONS::CURSOR_DOWN, etc.
The selection tool: currently supports:
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
bool IsFootprintEditor() const
bool GetMoveWarpsCursor() const
Indicate that a move operation should warp the mouse pointer to the origin of the move object.
Definition: tools_holder.h:140
void Activate()
Run the tool.
static TOOL_ACTION undo
Definition: actions.h:67
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:460
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
Definition: pad.h:60
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
static TOOL_ACTION moveWithReference
move with a reference point
Definition: pcb_actions.h:99
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
Definition: tool_manager.h:267
const LSET GetSelectionLayers()
static TOOL_ACTION duplicate
Definition: actions.h:74
static TOOL_ACTION refreshPreview
Definition: actions.h:109
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:203
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References _, TOOL_INTERACTIVE::Activate(), COLLECTOR::Append(), BUT_LEFT, SELECTION::ClearReferencePoint(), PCB_TOOL_BASE::controls(), ACTIONS::CURSOR_DOWN, ACTIONS::CURSOR_LEFT, ACTIONS::CURSOR_RIGHT, ACTIONS::CURSOR_UP, PNS::DM_ANY, ACTIONS::doDelete, ACTIONS::duplicate, SELECTION::Empty(), PCB_TOOL_BASE::footprint(), KIGFX::VIEW_CONTROLS::ForceCursorPosition(), PCB_TOOL_BASE::frame(), SELECTION::Front(), PCB_BASE_FRAME::GetCanvas(), TOOL_EVENT::GetCommandStr(), COLLECTOR::GetCount(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_BASE_FRAME::GetMagneticItemsSettings(), KIGFX::VIEW_CONTROLS::GetMousePosition(), TOOLS_HOLDER::GetMoveWarpsCursor(), BOARD_ITEM::GetParent(), SELECTION::GetReferencePoint(), PCB_SELECTION::GetSelectionLayers(), KIGFX::VIEW_CONTROLS::GetSettings(), TOOL_BASE::getView(), TOOL_BASE::getViewControls(), grid, group, COLLECTOR::HasItem(), SELECTION::HasReferencePoint(), PCB_ACTIONS::hideDynamicRatsnest, invokeInlineRouter(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), isInteractiveDragEnabled(), BOARD_ITEM::IsLocked(), m_commit, m_cursor, m_dragging, PCB_TOOL_BASE::m_isFootprintEditor, KIGFX::VC_SETTINGS::m_lastKeyboardCursorCommand, KIGFX::VC_SETTINGS::m_lastKeyboardCursorPositionValid, m_selectionTool, TOOL_BASE::m_toolMgr, MD_ALT, MD_SHIFT, PCB_ACTIONS::move, BOARD_ITEM::Move(), PCB_ACTIONS::moveExact, PCB_ACTIONS::moveWithReference, MOVING, pad, FOOTPRINT::Pads(), PCB_GROUP_T, PCB_MARKER_T, PCB_PAD_T, pickReferencePoint(), TOOLS_HOLDER::PopTool(), TOOL_MANAGER::PostEvent(), TOOLS_HOLDER::PushTool(), ACTIONS::refreshPreview, COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, EVENTS::SelectedItemsMoved, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItems, KIGFX::VIEW_CONTROLS::SetAutoPan(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), KIGFX::VIEW_CONTROLS::SetCursorPosition(), SELECTION::SetReferencePoint(), KIGFX::VIEW_CONTROLS::ShowCursor(), TC_MOUSE, EDA_ITEM::Type(), ACTIONS::undo, PCB_BASE_EDIT_FRAME::UndoRedoBlock(), PCB_ACTIONS::updateLocalRatsnest, TOOL_INTERACTIVE::Wait(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Move(), 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 244 of file edit_tool.cpp.

245 {
246  int mode = PNS::DM_ANY;
247 
248  if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
249  mode |= PNS::DM_FREE_ANGLE;
250 
252  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
253  {
254  // Iterate from the back so we don't have to worry about removals.
255  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
256  {
257  BOARD_ITEM* item = aCollector[ i ];
258 
259  // We don't operate on pads; convert them to footprint selections
260  if( !sTool->IsFootprintEditor() && item->IsLocked() && item->Type() == PCB_PAD_T
261  && !item->GetParent()->IsLocked() )
262  {
263  aCollector.Remove( item );
264 
265  if( item->GetParent() && !aCollector.HasItem( item->GetParent() ) )
266  aCollector.Append( item->GetParent() );
267  }
268  }
269 
270  sTool->FilterCollectorForGroups( aCollector );
271  },
272  !m_isFootprintEditor /* prompt user regarding locked items */ );
273 
274  if( selection.Empty() )
275  return 0;
276 
277  if( selection.Size() == 1 && selection.Front()->Type() == PCB_ARC_T )
278  {
279  // TODO: This really should be done in PNS to ensure DRC is maintained, but for now
280  // it allows interactive editing of an arc track
281  return DragArcTrack( aEvent );
282  }
283  else
284  {
285  invokeInlineRouter( mode );
286  }
287 
288  return 0;
289 }
int DragArcTrack(const TOOL_EVENT &aEvent)
Drag-resize an arc (and change end points of connected straight segments).
Definition: edit_tool.cpp:292
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:142
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
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:70
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:105
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
const PCB_SELECTION & selection() const
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
Definition: collector.h:203
bool m_isFootprintEditor
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
virtual bool IsLocked() const
Definition: board_item.h:249
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:200
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
The selection tool: currently supports:
bool IsFootprintEditor() const
void FilterCollectorForGroups(GENERAL_COLLECTOR &aCollector) const
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
EDA_ITEM * Front() const
Definition: selection.h:203
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References COLLECTOR::Append(), PNS::DM_ANY, PNS::DM_FREE_ANGLE, DragArcTrack(), PCB_ACTIONS::dragFreeAngle, SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForGroups(), SELECTION::Front(), COLLECTOR::GetCount(), BOARD_ITEM::GetParent(), COLLECTOR::HasItem(), invokeInlineRouter(), TOOL_EVENT::IsAction(), PCB_TOOL_BASE::IsFootprintEditor(), BOARD_ITEM::IsLocked(), PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, PCB_ARC_T, PCB_PAD_T, COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), PCB_TOOL_BASE::selection(), SELECTION::Size(), and EDA_ITEM::Type().

Referenced by setTransitions().

◆ DragArcTrack()

int EDIT_TOOL::DragArcTrack ( const TOOL_EVENT aEvent)

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

Definition at line 292 of file edit_tool.cpp.

293 {
295 
296  if( selection.Size() != 1 || selection.Front()->Type() != PCB_ARC_T )
297  return 0;
298 
299  Activate();
300 
301  ARC* theArc = static_cast<ARC*>( selection.Front() );
302  double arcAngleDegrees = std::abs( theArc->GetAngle() ) / 10.0;
303 
304  if( arcAngleDegrees + ADVANCED_CFG::GetCfg().m_MaxTangentAngleDeviation >= 180.0 )
305  {
307  wxString::Format( _( "Unable to resize arc tracks %.1f degrees or greater." ),
308  180.0 - ADVANCED_CFG::GetCfg().m_MaxTangentAngleDeviation ) );
309  return 0; // don't bother with > 180 degree arcs
310  }
311 
313 
314  controls->ShowCursor( true );
315  controls->SetAutoPan( true );
316  bool restore_state = false;
317 
318  VECTOR2I arcCenter = theArc->GetCenter();
319  SEG tanStart = SEG( arcCenter, theArc->GetStart() ).PerpendicularSeg( theArc->GetStart() );
320  SEG tanEnd = SEG( arcCenter, theArc->GetEnd() ).PerpendicularSeg( theArc->GetEnd() );
321 
322  //Ensure the tangent segments are in the correct orientation
323  VECTOR2I tanIntersect = tanStart.IntersectLines( tanEnd ).get();
324  tanStart.A = tanIntersect;
325  tanStart.B = theArc->GetStart();
326  tanEnd.A = tanIntersect;
327  tanEnd.B = theArc->GetEnd();
328 
329  KICAD_T track_types[] = { PCB_PAD_T, PCB_VIA_T, PCB_TRACE_T, PCB_ARC_T, EOT };
330 
331  auto getUniqueTrackAtAnchorCollinear =
332  [&]( const VECTOR2I& aAnchor, const SEG& aCollinearSeg ) -> TRACK*
333  {
334  auto conn = board()->GetConnectivity();
335 
336  // Allow items at a distance within the width of the arc track
337  int allowedDeviation = theArc->GetWidth();
338 
339  std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
340 
341  for( int i = 0; i < 3; i++ )
342  {
343  itemsOnAnchor = conn->GetConnectedItemsAtAnchor( theArc, aAnchor, track_types,
344  allowedDeviation );
345  allowedDeviation /= 2;
346 
347  if( itemsOnAnchor.size() == 1 )
348  break;
349  }
350 
351  TRACK* retval = nullptr;
352 
353  if( itemsOnAnchor.size() == 1 && itemsOnAnchor.front()->Type() == PCB_TRACE_T )
354  {
355  retval = static_cast<TRACK*>( itemsOnAnchor.front() );
356  SEG trackSeg( retval->GetStart(), retval->GetEnd() );
357 
358  // Allow deviations in colinearity as defined in ADVANCED_CFG
359  if( trackSeg.AngleDegrees( aCollinearSeg )
361  {
362  retval = nullptr;
363  }
364  }
365 
366  if( !retval )
367  {
368  retval = new TRACK( theArc->GetParent() );
369  retval->SetStart( (wxPoint) aAnchor );
370  retval->SetEnd( (wxPoint) aAnchor );
371  retval->SetNet( theArc->GetNet() );
372  retval->SetLayer( theArc->GetLayer() );
373  retval->SetWidth( theArc->GetWidth() );
374  retval->SetFlags( IS_NEW );
375  getView()->Add( retval );
376  }
377 
378  return retval;
379  };
380 
381  TRACK* trackOnStart = getUniqueTrackAtAnchorCollinear( theArc->GetStart(), tanStart);
382  TRACK* trackOnEnd = getUniqueTrackAtAnchorCollinear( theArc->GetEnd(), tanEnd );
383 
384  // Make copies of items to be edited
385  ARC* theArcCopy = new ARC( *theArc );
386  TRACK* trackOnStartCopy = new TRACK( *trackOnStart );
387  TRACK* trackOnEndCopy = new TRACK( *trackOnEnd );
388 
389  if( trackOnStart->GetLength() != 0 )
390  {
391  tanStart.A = trackOnStart->GetStart();
392  tanStart.B = trackOnStart->GetEnd();
393  }
394 
395  if( trackOnEnd->GetLength() != 0 )
396  {
397  tanEnd.A = trackOnEnd->GetStart();
398  tanEnd.B = trackOnEnd->GetEnd();
399  }
400 
401  // Recalculate intersection point
402  tanIntersect = tanStart.IntersectLines( tanEnd ).get();
403 
404  auto isTrackStartClosestToArcStart =
405  [&]( TRACK* aPointA ) -> bool
406  {
407  return GetLineLength( aPointA->GetStart(), theArc->GetStart() )
408  < GetLineLength( aPointA->GetEnd(), theArc->GetStart() );
409  };
410 
411  bool isStartTrackOnStartPt = isTrackStartClosestToArcStart( trackOnStart );
412  bool isEndTrackOnStartPt = isTrackStartClosestToArcStart( trackOnEnd );
413 
414  // Calculate constraints
415  //======================
416  // maxTanCircle is the circle with maximum radius that is tangent to the two adjacent straight
417  // tracks and whose tangent points are constrained within the original tracks and their
418  // projected intersection points.
419  //
420  // The cursor will be constrained first within the isosceles triangle formed by the segments
421  // cSegTanStart, cSegTanEnd and cSegChord. After that it will be constratined to be outside
422  // maxTanCircle.
423  //
424  //
425  // ____________ <-cSegTanStart
426  // / * . ' *
427  // cSegTanEnd-> / * . ' *
428  // /* . ' <-cSegChord *
429  // /. '
430  // /* *
431  //
432  // * c * <-maxTanCircle
433  //
434  // * *
435  //
436  // * *
437  // * *
438  // * *
439  //
440 
441  auto getFurthestPointToTanInterstect =
442  [&]( VECTOR2I& aPointA, VECTOR2I& aPointB ) -> VECTOR2I
443  {
444  if( ( aPointA - tanIntersect ).EuclideanNorm()
445  > ( aPointB - tanIntersect ).EuclideanNorm() )
446  {
447  return aPointA;
448  }
449  else
450  {
451  return aPointB;
452  }
453  };
454 
455  CIRCLE maxTanCircle;
456 
457  VECTOR2I tanStartPoint = getFurthestPointToTanInterstect( tanStart.A, tanStart.B );
458  VECTOR2I tanEndPoint = getFurthestPointToTanInterstect( tanEnd.A, tanEnd.B );
459  VECTOR2I tempTangentPoint = tanEndPoint;
460 
461  if( getFurthestPointToTanInterstect( tanStartPoint, tanEndPoint ) == tanEndPoint )
462  tempTangentPoint = tanStartPoint;
463 
464  maxTanCircle.ConstructFromTanTanPt( tanStart, tanEnd, tempTangentPoint );
465  VECTOR2I maxTanPtStart = tanStart.LineProject( maxTanCircle.Center );
466  VECTOR2I maxTanPtEnd = tanEnd.LineProject( maxTanCircle.Center );
467 
468  SEG cSegTanStart( maxTanPtStart, tanIntersect );
469  SEG cSegTanEnd( maxTanPtEnd, tanIntersect );
470  SEG cSegChord( maxTanPtStart, maxTanPtEnd );
471 
472  int cSegTanStartSide = cSegTanStart.Side( theArc->GetMid() );
473  int cSegTanEndSide = cSegTanEnd.Side( theArc->GetMid() );
474  int cSegChordSide = cSegChord.Side( theArc->GetMid() );
475 
476  // Start the tool loop
477  //====================
478  while( TOOL_EVENT* evt = Wait() )
479  {
481 
482  // Constrain cursor within the isosceles triangle
483  if( cSegTanStartSide != cSegTanStart.Side( m_cursor )
484  || cSegTanEndSide != cSegTanEnd.Side( m_cursor )
485  || cSegChordSide != cSegChord.Side( m_cursor ) )
486  {
487  std::vector<VECTOR2I> possiblePoints;
488 
489  possiblePoints.push_back( cSegTanEnd.NearestPoint( m_cursor ) );
490  possiblePoints.push_back( cSegChord.NearestPoint( m_cursor ) );
491 
492  VECTOR2I closest = cSegTanStart.NearestPoint( m_cursor );
493 
494  for( VECTOR2I candidate : possiblePoints )
495  {
496  if( ( candidate - m_cursor ).EuclideanNorm()
497  < ( closest - m_cursor ).EuclideanNorm() )
498  {
499  closest = candidate;
500  }
501  }
502 
503  m_cursor = closest;
504  }
505 
506  // Constrain cursor to be outside maxTanCircle
507  if( ( m_cursor - maxTanCircle.Center ).EuclideanNorm() < maxTanCircle.Radius )
508  m_cursor = maxTanCircle.NearestPoint( m_cursor );
509 
511 
512  // Calculate resulting object coordinates
513  CIRCLE circlehelper;
514  circlehelper.ConstructFromTanTanPt( cSegTanStart, cSegTanEnd, m_cursor );
515 
516  VECTOR2I newCenter = circlehelper.Center;
517  VECTOR2I newStart = cSegTanStart.LineProject( newCenter );
518  VECTOR2I newEnd = cSegTanEnd.LineProject( newCenter );
519  VECTOR2I newMid = GetArcMid( newStart, newEnd, newCenter );
520 
521  //Update objects
522  theArc->SetStart( (wxPoint) newStart );
523  theArc->SetEnd( (wxPoint) newEnd );
524  theArc->SetMid( (wxPoint) newMid );
525 
526  if( isStartTrackOnStartPt )
527  trackOnStart->SetStart( (wxPoint) newStart );
528  else
529  trackOnStart->SetEnd( (wxPoint) newStart );
530 
531  if( isEndTrackOnStartPt )
532  trackOnEnd->SetStart( (wxPoint) newEnd );
533  else
534  trackOnEnd->SetEnd( (wxPoint) newEnd );
535 
536  //Update view
537  getView()->Update( trackOnStart );
538  getView()->Update( trackOnEnd );
539  getView()->Update( theArc );
540 
541  //Handle events
542  if( evt->IsCancelInteractive() || evt->IsActivate() )
543  {
544  restore_state = true; // Canceling the tool means that items have to be restored
545  break; // Finish
546  }
547  else if( evt->IsAction( &ACTIONS::undo ) )
548  {
549  restore_state = true; // Perform undo locally
550  break; // Finish
551  }
552  else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT )
553  || evt->IsDblClick( BUT_LEFT ) )
554  {
555  break; // Finish
556  }
557  }
558 
559  // Ensure we only do one commit operation on each object
560  auto processTrack =
561  [&]( TRACK* aTrack, TRACK* aTrackCopy, int aMaxLengthIU ) -> bool
562  {
563  if( aTrack->IsNew() )
564  {
565  getView()->Remove( aTrack );
566 
567  if( aTrack->GetLength() <= aMaxLengthIU )
568  {
569  delete aTrack;
570  delete aTrackCopy;
571  aTrack = nullptr;
572  aTrackCopy = nullptr;
573  return false;
574  }
575  else
576  {
577  m_commit->Add( aTrack );
578  delete aTrackCopy;
579  aTrackCopy = nullptr;
580  return true;
581  }
582  }
583  else if( aTrack->GetLength() <= aMaxLengthIU )
584  {
585  aTrack->SwapData( aTrackCopy ); //restore the original before notifying COMMIT
586  m_commit->Remove( aTrack );
587  delete aTrackCopy;
588  aTrackCopy = nullptr;
589  return false;
590  }
591  else
592  {
593  m_commit->Modified( aTrack, aTrackCopy );
594  }
595 
596  return true;
597  };
598 
599  // Ammend the end points of the arc if we delete the joining tracks
600  wxPoint newStart = trackOnStart->GetStart();
601  wxPoint newEnd = trackOnEnd->GetStart();
602 
603  if( isStartTrackOnStartPt )
604  newStart = trackOnStart->GetEnd();
605 
606  if( isEndTrackOnStartPt )
607  newEnd = trackOnEnd->GetEnd();
608 
609  int maxLengthIU = KiROUND( ADVANCED_CFG::GetCfg().m_MaxTrackLengthToKeep * IU_PER_MM );
610 
611  if( !processTrack( trackOnStart, trackOnStartCopy, maxLengthIU ) )
612  theArc->SetStart( newStart );
613 
614  if( !processTrack( trackOnEnd, trackOnEndCopy, maxLengthIU ) )
615  theArc->SetEnd( newEnd );
616 
617  processTrack( theArc, theArcCopy, 0 ); // only delete the arc if start and end points coincide
618 
619  // Should we commit?
620  if( restore_state )
621  m_commit->Revert();
622  else
623  m_commit->Push( _( "Drag Arc Track" ) );
624 
625  return 0;
626 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
VECTOR2I m_cursor
Definition: edit_tool.h:193
virtual wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition: track.h:301
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:223
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.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
BOARD * board() const
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:194
void SetEnd(const wxPoint &aEnd)
Definition: track.h:112
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
const wxPoint & GetStart() const
Definition: track.h:116
static constexpr double IU_PER_MM
Mock up a conversion function.
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:352
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
class PAD, a pad in a footprint
Definition: typeinfo.h:89
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition: seg.h:201
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
CIRCLE & ConstructFromTanTanPt(const SEG &aLineA, const SEG &aLineB, const VECTOR2I &aP)
Constructs this circle such that it is tangent to the given segmetns and passes through the given poi...
Definition: circle.cpp:51
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
bool IsNew() const
Definition: eda_item.h:169
void SetWidth(int aWidth)
Definition: track.h:109
PCB_BASE_EDIT_FRAME * frame() const
PCB_SELECTION & GetSelection()
Return the set of currently selected items.
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition: seg.h:397
const wxPoint & GetMid() const
Definition: track.h:292
const PCB_SELECTION & selection() const
void SetFlags(STATUS_FLAGS aMask)
Definition: eda_item.h:203
const VECTOR2I GetArcMid(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
Returns the middle point of an arc, half-way between aStart and aEnd.
Definition: trigo.cpp:162
Generic, UI-independent tool event.
Definition: tool_event.h:173
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:416
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
int Radius
Public to make access simpler.
Definition: circle.h:36
Class Circle Represents basic circle geometry with utility geometry functions.
Definition: circle.h:33
void SetMid(const wxPoint &aMid)
Definition: track.h:291
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
Definition: track.cpp:904
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
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
Definition: seg.h:41
double GetAngle() const
Definition: track.cpp:938
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
double m_MaxTangentAngleDeviation
Maximum angle between the tangent line of an arc track and a connected straight track in order to com...
KIGFX::VIEW_CONTROLS * controls() const
int GetWidth() const
Definition: track.h:110
Definition: track.h:262
#define _(s)
Definition: 3d_actions.cpp:33
VECTOR2I A
Definition: seg.h:49
VECTOR2I Center
Public to make access simpler.
Definition: circle.h:37
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
void ShowInfoBarError(const wxString &aErrorMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an error icon on the left o...
const wxPoint & GetEnd() const
Definition: track.h:113
virtual double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
Definition: track.h:141
void Activate()
Run the tool.
void SetStart(const wxPoint &aStart)
Definition: track.h:115
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
static TOOL_ACTION undo
Definition: actions.h:67
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:322
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
#define IS_NEW
New item, just created.
Definition: eda_item.h:107
Definition: track.h:83
EDA_ITEM * Front() const
Definition: selection.h:203
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1503
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163
VECTOR2I NearestPoint(const VECTOR2I &aP) const
Function NearestPoint()
Definition: circle.cpp:188
VECTOR2I B
Definition: seg.h:50

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

Referenced by Drag().

◆ Duplicate()

int EDIT_TOOL::Duplicate ( const TOOL_EVENT aEvent)

Duplicate the current selection and starts a move action.

Definition at line 2036 of file edit_tool.cpp.

2037 {
2038  if( isRouterActive() )
2039  {
2040  wxBell();
2041  return 0;
2042  }
2043 
2044  bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
2045 
2046  // Be sure that there is at least one item that we can modify
2048  []( const VECTOR2I&, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2049  {
2050  std::set<BOARD_ITEM*> added_items;
2051 
2052  // Iterate from the back so we don't have to worry about removals.
2053  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
2054  {
2055  BOARD_ITEM* item = aCollector[i];
2056 
2057  // We don't operate on pads; convert them to footprint selections
2058  if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T
2059  && !item->GetParent()->IsLocked() )
2060  {
2061  aCollector.Remove( item );
2062 
2063  if( item->GetParent() && !aCollector.HasItem( item->GetParent() ) )
2064  added_items.insert( item->GetParent() );
2065  }
2066  }
2067 
2068  for( BOARD_ITEM* item : added_items )
2069  aCollector.Append( item );
2070 
2071  sTool->FilterCollectorForGroups( aCollector );
2072  } );
2073 
2074  if( selection.Empty() )
2075  return 0;
2076 
2077  // we have a selection to work on now, so start the tool process
2078  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
2079 
2080  // If the selection was given a hover, we do not keep the selection after completion
2081  bool is_hover = selection.IsHover();
2082 
2083  std::vector<BOARD_ITEM*> new_items;
2084  new_items.reserve( selection.Size() );
2085 
2086 
2087  // Each selected item is duplicated and pushed to new_items list
2088  // Old selection is cleared, and new items are then selected.
2089  for( EDA_ITEM* item : selection )
2090  {
2091  BOARD_ITEM* dupe_item = nullptr;
2092  BOARD_ITEM* orig_item = static_cast<BOARD_ITEM*>( item );
2093 
2094  if( m_isFootprintEditor )
2095  {
2096  FOOTPRINT* parentFootprint = editFrame->GetBoard()->GetFirstFootprint();
2097  dupe_item = parentFootprint->DuplicateItem( orig_item );
2098 
2099  if( increment && item->Type() == PCB_PAD_T
2100  && PAD_NAMING::PadCanHaveName( *static_cast<PAD*>( dupe_item ) ) )
2101  {
2102  PAD_TOOL* padTool = m_toolMgr->GetTool<PAD_TOOL>();
2103  wxString padName = padTool->GetLastPadName();
2104  padName = parentFootprint->GetNextPadName( padName );
2105  padTool->SetLastPadName( padName );
2106  static_cast<PAD*>( dupe_item )->SetName( padName );
2107  }
2108  }
2109  else if( orig_item->GetParent() && orig_item->GetParent()->Type() == PCB_FOOTPRINT_T )
2110  {
2111  FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( orig_item->GetParent() );
2112 
2113  m_commit->Modify( parentFootprint );
2114  dupe_item = parentFootprint->DuplicateItem( orig_item, true /* add to parent */ );
2115  }
2116  else
2117  {
2118  switch( orig_item->Type() )
2119  {
2120  case PCB_FOOTPRINT_T:
2121  case PCB_TEXT_T:
2122  case PCB_SHAPE_T:
2123  case PCB_TRACE_T:
2124  case PCB_ARC_T:
2125  case PCB_VIA_T:
2126  case PCB_ZONE_T:
2127  case PCB_TARGET_T:
2128  case PCB_DIM_ALIGNED_T:
2129  case PCB_DIM_CENTER_T:
2130  case PCB_DIM_ORTHOGONAL_T:
2131  case PCB_DIM_LEADER_T:
2132  dupe_item = orig_item->Duplicate();
2133  break;
2134 
2135  case PCB_GROUP_T:
2136  dupe_item = static_cast<PCB_GROUP*>( orig_item )->DeepDuplicate();
2137  break;
2138 
2139  case PCB_PAD_T:
2140  case PCB_FP_TEXT_T:
2141  case PCB_FP_SHAPE_T:
2142  case PCB_FP_ZONE_T:
2143  case PCB_MARKER_T:
2144  // Silently drop these items (such as footprint texts) from duplication
2145  break;
2146 
2147  default:
2148  wxASSERT_MSG( false,
2149  wxString::Format( "Unknown item type %d", orig_item->Type() ) );
2150  break;
2151  }
2152  }
2153 
2154  if( dupe_item )
2155  {
2156  if( dupe_item->Type() == PCB_GROUP_T )
2157  {
2158  static_cast<PCB_GROUP*>( dupe_item )->RunOnDescendants(
2159  [&]( BOARD_ITEM* bItem )
2160  {
2161  m_commit->Add( bItem );
2162  });
2163  }
2164 
2165  // Clear the selection flag here, otherwise the PCB_SELECTION_TOOL
2166  // will not properly select it later on
2167  dupe_item->ClearSelected();
2168 
2169  new_items.push_back( dupe_item );
2170  m_commit->Add( dupe_item );
2171  }
2172  }
2173 
2174  // Clear the old selection first
2176 
2177  // Select the new items
2178  m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
2179 
2180  // record the new items as added
2181  if( !selection.Empty() )
2182  {
2183  editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
2184  (int) new_items.size() ) );
2185 
2186  // TODO(ISM): This line can't be used to activate the tool until we allow multiple activations
2187  // m_toolMgr->RunAction( PCB_ACTIONS::move, true );
2188  // Instead we have to create the event and call the tool's function
2189  // directly
2190 
2191  // If items were duplicated, pick them up
2192  // this works well for "dropping" copies around and pushes the commit
2194  Move( evt );
2195 
2196  // Deslect the duplicated item if we originally started as a hover selection
2197  if( is_hover )
2199  }
2200 
2201  return 0;
2202 }
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: pcb_actions.h:70
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
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:1615
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:96
class ALIGNED_DIMENSION, a linear dimension (graphic item)
Definition: typeinfo.h:100
class LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:101
bool IsHover() const
Definition: selection.h:72
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
void ClearSelected()
Definition: eda_item.h:182
class CENTER_DIMENSION, a center point marking (graphic item)
Definition: typeinfo.h:102
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
Tool relating to pads and pad settings.
Definition: pad_tool.h:35
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
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:70
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:105
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:127
const PCB_SELECTION & selection() const
void SetLastPadName(const wxString &aPadName)
Definition: pad_tool.h:63
FOOTPRINT * GetFirstFootprint() const
Gets the first footprint on the board or nullptr.
Definition: board.h:382
wxString GetLastPadName() const
Definition: pad_tool.h:62
bool PadCanHaveName(const PAD &aPad)
Check if a pad should be named.
Definition: pad_naming.cpp:26
Generic, UI-independent tool event.
Definition: tool_event.h:173
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
Definition: collector.h:203
class ZONE, a copper pour area
Definition: typeinfo.h:105
bool m_isFootprintEditor
int Move(const TOOL_EVENT &aEvent)
Main loop in which events are handled.
Definition: edit_tool.cpp:629
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:104
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
virtual bool IsLocked() const
Definition: board_item.h:249
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:98
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
Common, abstract interface for edit frames.
#define _(s)
Definition: 3d_actions.cpp:33
wxString GetNextPadName(const wxString &aLastPadName) const
Return the next available pad name in the footprint.
Definition: footprint.cpp:1700
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
class ZONE, managed by a footprint
Definition: typeinfo.h:94
TOOL_EVENT MakeEvent() const
Return the event associated with the action (i.e.
Definition: tool_action.h:123
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
bool isRouterActive() const
Definition: edit_tool.cpp:236
The selection tool: currently supports:
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
bool IsFootprintEditor() const
virtual BOARD_ITEM * Duplicate() const
Create a copy of this BOARD_ITEM.
Definition: board_item.h:202
class ORTHOGONAL_DIMENSION, a linear dimension constrained to x/y
Definition: typeinfo.h:103
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
BOARD * GetBoard() const
void FilterCollectorForGroups(GENERAL_COLLECTOR &aCollector) const
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
void DisplayToolMsg(const wxString &msg) override
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References _, COLLECTOR::Append(), EDA_ITEM::ClearSelected(), EDA_DRAW_FRAME::DisplayToolMsg(), BOARD_ITEM::Duplicate(), PCB_ACTIONS::duplicateIncrement, FOOTPRINT::DuplicateItem(), SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForGroups(), Format(), PCB_BASE_FRAME::GetBoard(), COLLECTOR::GetCount(), BOARD::GetFirstFootprint(), PAD_TOOL::GetLastPadName(), FOOTPRINT::GetNextPadName(), BOARD_ITEM::GetParent(), TOOL_MANAGER::GetTool(), COLLECTOR::HasItem(), TOOL_EVENT::IsAction(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), BOARD_ITEM::IsLocked(), isRouterActive(), m_commit, PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, TOOL_ACTION::MakeEvent(), Move(), PCB_ACTIONS::move, PAD_NAMING::PadCanHaveName(), PCB_ARC_T, PCB_DIM_ALIGNED_T, PCB_DIM_CENTER_T, PCB_DIM_LEADER_T, PCB_DIM_ORTHOGONAL_T, PCB_FOOTPRINT_T, PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_FP_ZONE_T, PCB_GROUP_T, PCB_MARKER_T, PCB_PAD_T, PCB_SHAPE_T, PCB_TARGET_T, PCB_TEXT_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItems, PAD_TOOL::SetLastPadName(), 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 1109 of file edit_tool.cpp.

1110 {
1111  // Store last used fillet radius to allow pressing "enter" if repeat fillet is required
1112  static long long filletRadiusIU = 0;
1113 
1115  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1116  {
1117  // Iterate from the back so we don't have to worry about removals.
1118  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
1119  {
1120  BOARD_ITEM* item = aCollector[i];
1121 
1122  if( !dynamic_cast<TRACK*>( item ) )
1123  aCollector.Remove( item );
1124  }
1125  },
1126  !m_dragging /* prompt user regarding locked items */ );
1127 
1128  if( selection.Size() < 2 )
1129  {
1130  frame()->ShowInfoBarMsg( _( "At least two straight track segments must be selected." ) );
1131  return 0;
1132  }
1133 
1134  WX_UNIT_ENTRY_DIALOG dia( frame(), _( "Enter fillet radius:" ), _( "Fillet Tracks" ),
1135  filletRadiusIU );
1136 
1137  if( dia.ShowModal() == wxID_CANCEL )
1138  return 0;
1139 
1140  filletRadiusIU = dia.GetValue();
1141 
1142  if( filletRadiusIU == 0 )
1143  {
1144  frame()->ShowInfoBarMsg( _( "A radius of zero was entered.\n"
1145  "The fillet operation was not performed." ) );
1146  return 0;
1147  }
1148 
1149 
1150  struct FILLET_OP
1151  {
1152  TRACK* t1;
1153  TRACK* t2;
1154  //If true, start point of track is modified after ARC is added, otherwise the end point:
1155  bool t1Start = true;
1156  bool t2Start = true;
1157  };
1158 
1159  std::vector<FILLET_OP> filletOperations;
1160  KICAD_T track_types[] = { PCB_PAD_T, PCB_VIA_T, PCB_TRACE_T, PCB_ARC_T, EOT };
1161  bool operationPerformedOnAtLeastOne = false;
1162  bool didOneAttemptFail = false;
1163  std::set<TRACK*> processedTracks;
1164 
1165  for( auto it = selection.begin(); it != selection.end(); it++ )
1166  {
1167  TRACK* track = dyn_cast<TRACK*>( *it );
1168 
1169  if( !track || track->Type() != PCB_TRACE_T || track->IsLocked()
1170  || track->GetLength() == 0 )
1171  {
1172  continue;
1173  }
1174 
1175  auto processFilletOp =
1176  [&]( bool aStartPoint )
1177  {
1178  wxPoint anchor = ( aStartPoint ) ? track->GetStart() : track->GetEnd();
1179  auto connectivity = board()->GetConnectivity();
1180  auto itemsOnAnchor = connectivity->GetConnectedItemsAtAnchor( track, anchor,
1181  track_types );
1182 
1183  if( itemsOnAnchor.size() > 0
1184  && selection.Contains( itemsOnAnchor.at( 0 ) )
1185  && itemsOnAnchor.at( 0 )->Type() == PCB_TRACE_T )
1186  {
1187  TRACK* trackOther = dyn_cast<TRACK*>( itemsOnAnchor.at( 0 ) );
1188 
1189  // Make sure we don't fillet the same pair of tracks twice
1190  if( processedTracks.find( trackOther ) == processedTracks.end() )
1191  {
1192  if( itemsOnAnchor.size() == 1 )
1193  {
1194  FILLET_OP filletOp;
1195  filletOp.t1 = track;
1196  filletOp.t2 = trackOther;
1197  filletOp.t1Start = aStartPoint;
1198  filletOp.t2Start = track->IsPointOnEnds( filletOp.t2->GetStart() );
1199  filletOperations.push_back( filletOp );
1200  }
1201  else
1202  {
1203  // User requested to fillet these two tracks but not possible as
1204  // there are other elements connected at that point
1205  didOneAttemptFail = true;
1206  }
1207  }
1208  }
1209  };
1210 
1211  processFilletOp( true ); // on the start point of track
1212  processFilletOp( false ); // on the end point of track
1213 
1214  processedTracks.insert( track );
1215  }
1216 
1217  std::vector<BOARD_ITEM*> itemsToAddToSelection;
1218 
1219  for( FILLET_OP filletOp : filletOperations )
1220  {
1221  TRACK* track1 = filletOp.t1;
1222  TRACK* track2 = filletOp.t2;
1223 
1224  bool trackOnStart = track1->IsPointOnEnds( track2->GetStart() );
1225  bool trackOnEnd = track1->IsPointOnEnds( track2->GetEnd() );
1226 
1227  if( trackOnStart && trackOnEnd )
1228  continue; // Ignore duplicate tracks
1229 
1230  if( ( trackOnStart || trackOnEnd ) && track1->GetLayer() == track2->GetLayer() )
1231  {
1232  SEG t1Seg( track1->GetStart(), track1->GetEnd() );
1233  SEG t2Seg( track2->GetStart(), track2->GetEnd() );
1234 
1235  if( t1Seg.ApproxCollinear( t2Seg ) )
1236  continue;
1237 
1238  SHAPE_ARC sArc( t1Seg, t2Seg, filletRadiusIU );
1239 
1240  wxPoint t1newPoint, t2newPoint;
1241 
1242  auto setIfPointOnSeg =
1243  []( wxPoint& aPointToSet, SEG aSegment, VECTOR2I aVecToTest )
1244  {
1245  VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1246 
1247  // Find out if we are on the segment (minimum precision)
1248  if( segToVec.EuclideanNorm() < SHAPE_ARC::MIN_PRECISION_IU )
1249  {
1250  aPointToSet.x = aVecToTest.x;
1251  aPointToSet.y = aVecToTest.y;
1252  return true;
1253  }
1254 
1255  return false;
1256  };
1257 
1258  //Do not draw a fillet if the end points of the arc are not within the track segments
1259  if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.GetP0() )
1260  && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.GetP0() ) )
1261  {
1262  didOneAttemptFail = true;
1263  continue;
1264  }
1265 
1266  if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.GetP1() )
1267  && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.GetP1() ) )
1268  {
1269  didOneAttemptFail = true;
1270  continue;
1271  }
1272 
1273  ARC* tArc = new ARC( frame()->GetBoard(), &sArc );
1274  tArc->SetLayer( track1->GetLayer() );
1275  tArc->SetWidth( track1->GetWidth() );
1276  tArc->SetNet( track1->GetNet() );
1277  m_commit->Add( tArc );
1278  itemsToAddToSelection.push_back( tArc );
1279 
1280  m_commit->Modify( track1 );
1281  m_commit->Modify( track2 );
1282 
1283  if( filletOp.t1Start )
1284  track1->SetStart( t1newPoint );
1285  else
1286  track1->SetEnd( t1newPoint );
1287 
1288  if( filletOp.t2Start )
1289  track2->SetStart( t2newPoint );
1290  else
1291  track2->SetEnd( t2newPoint );
1292 
1293  operationPerformedOnAtLeastOne = true;
1294  }
1295  }
1296 
1297  m_commit->Push( _( "Fillet Tracks" ) );
1298 
1299  //select the newly created arcs
1300  for( BOARD_ITEM* item : itemsToAddToSelection )
1301  m_selectionTool->AddItemToSel( item );
1302 
1303  if( !operationPerformedOnAtLeastOne )
1304  frame()->ShowInfoBarMsg( _( "Unable to fillet the selected track segments." ) );
1305  else if( didOneAttemptFail )
1306  frame()->ShowInfoBarMsg( _( "Some of the track segments could not be filleted." ) );
1307 
1308  return 0;
1309 }
BOARD * board() const
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:194
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
void SetEnd(const wxPoint &aEnd)
Definition: track.h:112
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
const wxPoint & GetStart() const
Definition: track.h:116
ITER end()
Definition: selection.h:63
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
void SetWidth(int aWidth)
Definition: track.h:109
PCB_BASE_EDIT_FRAME * frame() const
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...
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
ITER begin()
Definition: selection.h:62
const PCB_SELECTION & selection() const
An extension of WX_TEXT_ENTRY_DIALOG that uses UNIT_BINDER to request a dimension (e....
bool m_dragging
Definition: edit_tool.h:192
void AddItemToSel(BOARD_ITEM *aItem, bool aQuietMode=false)
Select all items on the board.
static const int MIN_PRECISION_IU
This is the minimum precision for all the points in a shape.
Definition: shape.h:122
bool Contains(EDA_ITEM *aItem) const
Definition: selection.h:114
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:416
BOARD * GetBoard()
Definition: seg.h:41
virtual bool IsLocked() const
Definition: board_item.h:249
void SetNet(NETINFO_ITEM *aNetInfo)
Set a NET_INFO object for the item.
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
int GetWidth() const
Definition: track.h:110
STATUS_FLAGS IsPointOnEnds(const wxPoint &point, int min_dist=0) const
Function IsPointOnEnds returns STARTPOINT if point if near (dist = min_dist) start point,...
Definition: track.cpp:188
Definition: track.h:262
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
The selection tool: currently supports:
const wxPoint & GetEnd() const
Definition: track.h:113
virtual double GetLength() const
Function GetLength returns the length of the track using the hypotenuse calculation.
Definition: track.h:141
void SetStart(const wxPoint &aStart)
Definition: track.h:115
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
Definition: track.h:83
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

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

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 1619 of file edit_tool.cpp.

1620 {
1621  if( isRouterActive() )
1622  {
1623  wxBell();
1624  return 0;
1625  }
1626 
1628  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1629  {
1630  std::set<BOARD_ITEM*> added_items;
1631 
1632  // Iterate from the back so we don't have to worry about removals.
1633  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
1634  {
1635  BOARD_ITEM* item = aCollector[i];
1636 
1637  // We don't operate on pads; convert them to footprint selections
1638  if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T
1639  && !item->GetParent()->IsLocked() )
1640  {
1641  aCollector.Remove( item );
1642 
1643  if( item->GetParent() && !aCollector.HasItem( item->GetParent() ) )
1644  added_items.insert( item->GetParent() );
1645  }
1646 
1647  // We can't flip both a footprint and its text in the same operation, so if
1648  // both are selected, remove the text
1649  if( item->Type() == PCB_FP_TEXT_T && aCollector.HasItem( item->GetParent() ) )
1650  aCollector.Remove( item );
1651  }
1652 
1653  for( BOARD_ITEM* item : added_items )
1654  aCollector.Append( item );
1655 
1656  sTool->FilterCollectorForGroups( aCollector );
1657  },
1658  !m_dragging && !m_isFootprintEditor/* prompt user regarding locked items */ );
1659 
1660  if( selection.Empty() )
1661  return 0;
1662 
1663  OPT<VECTOR2I> oldRefPt = boost::make_optional<VECTOR2I>( false, VECTOR2I( 0, 0 ) );
1664 
1666  oldRefPt = selection.GetReferencePoint();
1667 
1669 
1670  // Flip around the anchor for footprints, and the bounding box center for board items
1671  VECTOR2I refPt = IsFootprintEditor() ? VECTOR2I( 0, 0 ) : selection.GetCenter();
1672 
1673  // If only one item selected, flip around the selection or item anchor point (instead
1674  // of the bounding box center) to avoid moving the item anchor
1675  if( selection.GetSize() == 1 )
1676  {
1678  refPt = selection.GetReferencePoint();
1679  else
1680  refPt = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) )->GetPosition();
1681  }
1682 
1683  bool leftRight = frame()->Settings().m_FlipLeftRight;
1684 
1685  // When editing footprints, all items have the same parent
1686  if( IsFootprintEditor() )
1687  m_commit->Modify( selection.Front() );
1688 
1689  for( EDA_ITEM* item : selection )
1690  {
1691  if( !item->IsNew() && !IsFootprintEditor() )
1692  m_commit->Modify( item );
1693 
1694  if( item->Type() == PCB_GROUP_T )
1695  {
1696  static_cast<PCB_GROUP*>( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem )
1697  {
1698  m_commit->Modify( bItem );
1699  });
1700  }
1701 
1702  static_cast<BOARD_ITEM*>( item )->Flip( refPt, leftRight );
1703  }
1704 
1705  if( !m_dragging )
1706  m_commit->Push( _( "Change Side / Flip" ) );
1707 
1708  if( selection.IsHover() && !m_dragging )
1710 
1712 
1713  if( m_dragging )
1715 
1716  // Restore the old reference so any mouse dragging that occurs doesn't make the selection jump
1717  // to this now invalid reference
1718  if( oldRefPt )
1719  selection.SetReferencePoint( *oldRefPt );
1720  else
1722 
1723  return 0;
1724 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
VECTOR2I GetReferencePoint() const
Definition: selection.h:259
void ClearReferencePoint()
Definition: selection.h:269
bool IsHover() const
Definition: selection.h:72
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:206
bool IsNew() const
Definition: eda_item.h:169
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:105
PCB_BASE_EDIT_FRAME * frame() const
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:264
const PCB_SELECTION & selection() const
bool updateModificationPoint(PCB_SELECTION &aSelection)
Definition: edit_tool.cpp:2279
bool m_dragging
Definition: edit_tool.h:192
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
Definition: collector.h:203
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.h:106
bool m_isFootprintEditor
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:101
virtual bool IsLocked() const
Definition: board_item.h:249
bool HasReferencePoint() const
Definition: selection.h:254
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
PCBNEW_SETTINGS & Settings()
bool isRouterActive() const
Definition: edit_tool.cpp:236
The selection tool: currently supports:
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
bool IsFootprintEditor() const
boost::optional< T > OPT
Definition: optional.h:7
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:460
void FilterCollectorForGroups(GENERAL_COLLECTOR &aCollector) const
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
EDA_ITEM * Front() const
Definition: selection.h:203
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References _, COLLECTOR::Append(), SELECTION::ClearReferencePoint(), SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForGroups(), PCB_TOOL_BASE::frame(), SELECTION::Front(), SELECTION::GetCenter(), COLLECTOR::GetCount(), SELECTION::GetItem(), BOARD_ITEM::GetParent(), SELECTION::GetReferencePoint(), SELECTION::GetSize(), COLLECTOR::HasItem(), SELECTION::HasReferencePoint(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), BOARD_ITEM::IsLocked(), isRouterActive(), m_commit, m_dragging, PCBNEW_SETTINGS::m_FlipLeftRight, PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, PCB_FP_TEXT_T, PCB_GROUP_T, PCB_PAD_T, TOOL_MANAGER::ProcessEvent(), COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, SELECTION::SetReferencePoint(), PCB_BASE_FRAME::Settings(), EDA_ITEM::Type(), PCB_ACTIONS::updateLocalRatsnest, and updateModificationPoint().

Referenced by 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 2266 of file edit_tool.cpp.

2268 {
2269  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2270  {
2271  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
2272 
2273  if( item->Type() != PCB_FOOTPRINT_T )
2274  aCollector.Remove( i );
2275  }
2276 }
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

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 155 of file pcb_tool_base.h.

156  {
157  return getEditFrame<PCB_BASE_EDIT_FRAME>();
158  }

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(), BOARD_INSPECTION_TOOL::CrossProbePcbToSch(), ROUTER_TOOL::CustomTrackWidthDialog(), FOOTPRINT_EDITOR_CONTROL::DeleteFootprint(), PCB_TOOL_BASE::displayOptions(), PCB_TOOL_BASE::doInteractiveItemPlacement(), doMoveSelection(), ROUTER_TOOL::DpDimensionsDialog(), DragArcTrack(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::drawSegment(), 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(), BOARD_INSPECTION_TOOL::HighlightItem(), FOOTPRINT_EDITOR_CONTROL::ImportFootprint(), BOARD_EDITOR_CONTROL::ImportSpecctraSession(), ROUTER_TOOL::Init(), PCB_SELECTION_TOOL::Init(), Init(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), DRAWING_TOOL::InteractivePlaceWithPreview(), PCB_PICKER_TOOL::Main(), PCB_SELECTION_TOOL::Main(), ROUTER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::meanderSettingsDialog(), MoveExact(), PCB_POINT_EDITOR::OnSelectionChange(), PCB_CONTROL::Paste(), PAD_TOOL::pastePadProperties(), ROUTER_TOOL::performDragging(), ROUTER_TOOL::performRouting(), LENGTH_TUNER_TOOL::performTuning(), GROUP_TOOL::PickNewMember(), PCB_CONTROL::placeBoardItems(), BOARD_EDITOR_CONTROL::PlaceFootprint(), BOARD_EDITOR_CONTROL::PlaceTarget(), DRAWING_TOOL::PlaceText(), ROUTER_TOOL::prepareInteractive(), PAD_TOOL::pushPadSettings(), PAD_TOOL::recombinePad(), POSITION_RELATIVE_TOOL::RelativeItemSelectionMove(), PCB_POINT_EDITOR::removeCorner(), PCB_SELECTION_TOOL::RequestSelection(), PNS::TOOL_BASE::Reset(), 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(), BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB(), ZONE_FILLER_TOOL::ZoneFill(), and ZONE_FILLER_TOOL::ZoneFillAll().

◆ GetAndPlace()

int EDIT_TOOL::GetAndPlace ( const TOOL_EVENT aEvent)

Definition at line 182 of file edit_tool.cpp.

183 {
185  FOOTPRINT* fp = getEditFrame<PCB_BASE_FRAME>()->GetFootprintFromBoardByReference();
186 
187  if( fp )
188  {
190  m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, (void*) fp );
191 
192  selectionTool->GetSelection().SetReferencePoint( fp->GetPosition() );
194  }
195 
196  return 0;
197 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:96
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
PCB_SELECTION & GetSelection()
Return the set of currently selected items.
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:264
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition: pcb_actions.h:66
The selection tool: currently supports:

References 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 158 of file edit_tool.h.

158 { return m_commit.get(); }
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191

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 185 of file tool_base.h.

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

References TOOL_BASE::getToolHolderInt().

Referenced by ZONE_CREATE_HELPER::createNewZone().

◆ 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 121 of file tool_base.h.

122  {
123  return m_toolId;
124  }
TOOL_ID m_toolId
Name of the tool.
Definition: tool_base.h:210

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

Return the instance of TOOL_MANAGER that takes care of the tool.

Returns
Instance of the TOOL_MANAGER or NULL if there is no associated tool manager.

Definition at line 144 of file tool_base.h.

145  {
146  return m_toolMgr;
147  }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215

References TOOL_BASE::m_toolMgr.

Referenced by BOARD_COMMIT::BOARD_COMMIT(), ZONE_CREATE_HELPER::commitZone(), ZONE_CREATE_HELPER::createNewZone(), PCB_TOOL_BASE::doInteractiveItemPlacement(), ACTION_MENU::getToolManager(), LIB_TREE::onContextMenu(), ZONE_CREATE_HELPER::OnFirstPoint(), ACTION_MENU::OnMenuEvent(), and ZONE_CREATE_HELPER::performZoneCutout().

◆ 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 197 of file tool_base.h.

References TOOL_BASE::getModelInt().

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

◆ 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 134 of file tool_base.h.

135  {
136  return m_toolName;
137  }
std::string m_toolName
Definition: tool_base.h:214

References TOOL_BASE::m_toolName.

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

◆ GetToolMenu()

◆ GetType()

TOOL_TYPE TOOL_BASE::GetType ( ) const
inlineinherited

Return the type of the tool.

Returns
The type of the tool.

Definition at line 109 of file tool_base.h.

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

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 }
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:289
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215

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(), PL_SELECTION_TOOL::ClearSelection(), EE_SELECTION_TOOL::ClearSelection(), EE_SELECTION_TOOL::CollectHits(), SCH_LINE_WIRE_BUS_TOOL::computeBreakPoint(), COMMON_TOOLS::CursorControl(), PL_EDIT_TOOL::DeleteItemCursor(), SCH_EDIT_TOOL::DeleteItemCursor(), PCB_CONTROL::DeleteItemCursor(), GERBVIEW_SELECTION_TOOL::disambiguationMenu(), PL_EDIT_TOOL::DoDelete(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), doMoveSelection(), PL_SELECTION_TOOL::doSelectionMenu(), EE_SELECTION_TOOL::doSelectionMenu(), PCB_SELECTION_TOOL::doSelectionMenu(), COMMON_TOOLS::doZoomFit(), COMMON_TOOLS::doZoomInOut(), COMMON_TOOLS::doZoomToPreset(), DragArcTrack(), DRAWING_TOOL::drawArc(), DRAWING_TOOL::DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::drawSegment(), SCH_LINE_WIRE_BUS_TOOL::DrawSegments(), PL_DRAWING_TOOLS::DrawShape(), DRAWING_TOOL::DrawZone(), BOARD_EDITOR_CONTROL::DrillOrigin(), SYMBOL_EDITOR_EDIT_TOOL::Duplicate(), PAD_TOOL::EnumeratePads(), SCH_EDITOR_CONTROL::FindComponentAndItem(), ROUTER_TOOL::getStartLayer(), PCB_CONTROL::GridResetOrigin(), PCB_CONTROL::GridSetOrigin(), ROUTER_TOOL::handleCommonEvents(), PL_SELECTION_TOOL::highlight(), EE_SELECTION_TOOL::highlight(), PCB_SELECTION_TOOL::highlight(), GERBVIEW_CONTROL::HighlightControl(), PNS::TOOL_BASE::highlightNet(), BOARD_INSPECTION_TOOL::highlightNet(), PCB_SELECTION_TOOL::hitTestDistance(), PCB_PICKER_TOOL::Main(), EE_POINT_EDITOR::Main(), PL_POINT_EDITOR::Main(), SCH_MOVE_TOOL::Main(), GERBVIEW_INSPECTION_TOOL::MeasureTool(), PCB_VIEWER_TOOLS::MeasureTool(), SCH_EDIT_TOOL::Mirror(), MoveExact(), SCH_MOVE_TOOL::moveItem(), PL_EDIT_TOOL::moveItem(), COMMON_TOOLS::OnGridChanged(), PCB_POINT_EDITOR::OnSelectionChange(), COMMON_TOOLS::PanControl(), PL_EDIT_TOOL::Paste(), SYMBOL_EDITOR_EDIT_TOOL::Paste(), SCH_EDITOR_CONTROL::Paste(), PNS::TOOL_BASE::pickSingleItem(), BOARD_EDITOR_CONTROL::PlaceFootprint(), PL_DRAWING_TOOLS::PlaceItem(), BOARD_EDITOR_CONTROL::PlaceTarget(), SCH_EDIT_TOOL::Properties(), Properties(), Remove(), BOARD_EDITOR_CONTROL::Reset(), PNS::TOOL_BASE::Reset(), PCB_CONTROL::Reset(), GERBVIEW_SELECTION_TOOL::Reset(), DRAWING_TOOL::Reset(), EE_SELECTION_TOOL::Reset(), PCB_SELECTION_TOOL::Reset(), EE_TOOL_BASE< SCH_BASE_FRAME >::Reset(), SCH_EDIT_TOOL::Rotate(), GERBVIEW_SELECTION_TOOL::select(), GERBVIEW_SELECTION_TOOL::selectable(), PCB_SELECTION_TOOL::Selectable(), PCB_SELECTION_TOOL::SelectAll(), EE_SELECTION_TOOL::SelectAll(), PL_SELECTION_TOOL::selectionContains(), EE_SELECTION_TOOL::selectionContains(), PL_SELECTION_TOOL::selectMultiple(), EE_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::ToggleHiddenFields(), SCH_EDITOR_CONTROL::ToggleHiddenPins(), SCH_DRAWING_TOOLS::TwoClickPlace(), PL_SELECTION_TOOL::unhighlight(), EE_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< SCH_BASE_FRAME >::updateItem(), SCH_EDITOR_CONTROL::UpdateNetHighlighting(), EE_POINT_EDITOR::updateParentItem(), EE_POINT_EDITOR::updatePoints(), PL_POINT_EDITOR::updatePoints(), PCB_POINT_EDITOR::updatePoints(), PCB_SELECTION_TOOL::updateSelection(), PNS::TOOL_BASE::updateStartItem(), PCB_VIEWER_TOOLS::view(), PCB_TOOL_BASE::view(), 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 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
KIGFX::VIEW_CONTROLS * GetViewControls() const
Definition: tool_manager.h:291

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(), SCH_EDIT_TOOL::BreakWire(), 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(), 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(), BOARD_INSPECTION_TOOL::HighlightNet(), SCH_EDITOR_CONTROL::HighlightNet(), BOARD_INSPECTION_TOOL::HighlightNetTool(), FOOTPRINT_EDITOR_CONTROL::ImportFootprint(), PCB_PICKER_TOOL::Main(), EE_POINT_EDITOR::Main(), PL_EDIT_TOOL::Main(), SYMBOL_EDITOR_MOVE_TOOL::Main(), PL_POINT_EDITOR::Main(), SCH_MOVE_TOOL::Main(), EE_SELECTION_TOOL::Main(), 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(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), BOARD_EDITOR_CONTROL::PlaceTarget(), SCH_EDIT_TOOL::Properties(), Properties(), Remove(), SCH_EDIT_TOOL::RepeatDrawItem(), PL_SELECTION_TOOL::RequestSelection(), EE_SELECTION_TOOL::RequestSelection(), PCB_POINT_EDITOR::Reset(), DRAWING_TOOL::Reset(), COMMON_TOOLS::ResetLocalCoords(), GERBVIEW_SELECTION_TOOL::selectCursor(), PCB_SELECTION_TOOL::selectCursor(), PL_SELECTION_TOOL::selectMultiple(), EE_SELECTION_TOOL::selectMultiple(), PCB_SELECTION_TOOL::selectMultiple(), EE_SELECTION_TOOL::SelectNode(), ZOOM_TOOL::selectRegion(), ALIGN_DISTRIBUTE_TOOL::selectTarget(), PCB_PICKER_TOOL::setControls(), PICKER_TOOL::setControls(), EE_POINT_EDITOR::setEditedPoint(), PL_POINT_EDITOR::setEditedPoint(), PCB_POINT_EDITOR::setEditedPoint(), SCH_DRAWING_TOOLS::SingleClickPlace(), SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace(), SCH_DRAWING_TOOLS::TwoClickPlace(), EE_POINT_EDITOR::updateEditedPoint(), PL_POINT_EDITOR::updateEditedPoint(), PCB_POINT_EDITOR::updateEditedPoint(), PCB_POINT_EDITOR::updateItem(), PL_EDIT_TOOL::updateModificationPoint(), 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 128 of file tool_interactive.h.

130 {
131  TOOL_STATE_FUNC sptr = std::bind( aStateFunc, static_cast<T*>( this ), std::placeholders::_1 );
132 
133  goInternal( sptr, aConditions );
134 }
std::function< int(const TOOL_EVENT &)> TOOL_STATE_FUNC
Definition: tool_base.h:59
void goInternal(TOOL_STATE_FUNC &aState, const TOOL_EVENT_LIST &aConditions)

References TOOL_INTERACTIVE::goInternal().

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

◆ Init()

bool EDIT_TOOL::Init ( void  )
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 101 of file edit_tool.cpp.

102 {
103  // Find the selection tool, so they can cooperate
105 
106  auto inFootprintEditor =
107  [ this ]( const SELECTION& aSelection )
108  {
109  return m_isFootprintEditor;
110  };
111 
112  auto singleFootprintCondition = SELECTION_CONDITIONS::OnlyType( PCB_FOOTPRINT_T )
114 
115  auto noActiveToolCondition =
116  [ this ]( const SELECTION& aSelection )
117  {
118  return frame()->ToolStackIsEmpty();
119  };
120 
121  auto notMovingCondition =
122  [ this ]( const SELECTION& aSelection )
123  {
126  };
127 
128  auto noItemsCondition =
129  [ this ]( const SELECTION& aSelections ) -> bool
130  {
131  return frame()->GetBoard() && !frame()->GetBoard()->IsEmpty();
132  };
133 
134  // Add context menu entries that are displayed when selection tool is active
136 
137  menu.AddItem( PCB_ACTIONS::move, SELECTION_CONDITIONS::NotEmpty && notMovingCondition );
149  menu.AddItem( PCB_ACTIONS::mirror, inFootprintEditor && SELECTION_CONDITIONS::NotEmpty );
150 
153 
154  // Footprint actions
155  menu.AddSeparator();
156  menu.AddItem( PCB_ACTIONS::editFpInFpEditor, singleFootprintCondition );
157  menu.AddItem( PCB_ACTIONS::updateFootprint, singleFootprintCondition );
158  menu.AddItem( PCB_ACTIONS::changeFootprint, singleFootprintCondition );
159 
160  // Add the submenu for create array and special move
161  auto specialToolsSubMenu = std::make_shared<SPECIAL_TOOLS_CONTEXT_MENU>( this );
162  menu.AddSeparator();
163  m_selectionTool->GetToolMenu().AddSubMenu( specialToolsSubMenu );
164  menu.AddMenu( specialToolsSubMenu.get(), SELECTION_CONDITIONS::NotEmpty, 100 );
165 
166  menu.AddSeparator( 150 );
169  // Selection tool handles the context menu for some other tools, such as the Picker.
170  // Don't add things like Paste when another tool is active.
171  menu.AddItem( ACTIONS::paste, noActiveToolCondition, 150 );
174 
175  menu.AddSeparator( 150 );
176  menu.AddItem( ACTIONS::selectAll, noItemsCondition, 150 );
177 
178  return true;
179 }
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
bool IsCurrentTool(const TOOL_ACTION &aAction) const
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:96
static const KICAD_T Tracks[]
A scan list for only TRACKs.
Definition: collectors.h:299
static TOOL_ACTION editFpInFpEditor
Definition: pcb_actions.h:346
static TOOL_ACTION doDelete
Definition: actions.h:75
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
Create a functor that tests if the selected items are only of given types.
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:142
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
static TOOL_ACTION properties
Activation of the edit tool.
Definition: pcb_actions.h:121
TOOL_MENU & GetToolMenu()
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:141
static TOOL_ACTION mirror
Mirroring of selected items.
Definition: pcb_actions.h:112
static TOOL_ACTION changeFootprint
Definition: pcb_actions.h:326
static TOOL_ACTION updateFootprint
Definition: pcb_actions.h:324
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
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 bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
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:118
PCB_BASE_EDIT_FRAME * frame() const
static TOOL_ACTION copy
Definition: actions.h:70
static TOOL_ACTION rotateCw
Rotation of selected objects.
Definition: pcb_actions.h:105
static TOOL_ACTION cut
Definition: actions.h:69
bool ToolStackIsEmpty()
Definition: tools_holder.h:117
bool m_isFootprintEditor
static TOOL_ACTION inlineBreakTrack
Breaks track when router is not activated.
Definition: pcb_actions.h:139
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:106
static TOOL_ACTION flip
Flipping of selected objects.
Definition: pcb_actions.h:109
static const KICAD_T DraggableItems[]
A scan list for items that can be dragged.
Definition: collectors.h:314
void AddSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition: tool_menu.cpp:52
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Create a functor that tests if the selected items are only of given type.
The selection tool: currently supports:
BOARD * GetBoard() const
static TOOL_ACTION moveWithReference
move with a reference point
Definition: pcb_actions.h:99
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.
static TOOL_ACTION selectAll
Definition: actions.h:73
bool IsEmpty() const
Definition: board.h:353
static TOOL_ACTION paste
Definition: actions.h:71
static TOOL_ACTION duplicate
Definition: actions.h:74

References CONDITIONAL_MENU::AddItem(), CONDITIONAL_MENU::AddMenu(), CONDITIONAL_MENU::AddSeparator(), TOOL_MENU::AddSubMenu(), PCB_ACTIONS::changeFootprint, ACTIONS::copy, SELECTION_CONDITIONS::Count(), 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(), TOOL_MENU::GetMenu(), TOOL_MANAGER::GetTool(), TOOL_INTERACTIVE::GetToolMenu(), PCB_ACTIONS::inlineBreakTrack, TOOLS_HOLDER::IsCurrentTool(), BOARD::IsEmpty(), PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, PCB_ACTIONS::mirror, PCB_ACTIONS::move, PCB_ACTIONS::moveWithReference, SELECTION_CONDITIONS::NotEmpty(), SELECTION_CONDITIONS::OnlyType(), SELECTION_CONDITIONS::OnlyTypes(), ACTIONS::paste, PCB_FOOTPRINT_T, PCB_ACTIONS::properties, PCB_ACTIONS::rotateCcw, PCB_ACTIONS::rotateCw, ACTIONS::selectAll, TOOLS_HOLDER::ToolStackIsEmpty(), GENERAL_COLLECTOR::Tracks, and PCB_ACTIONS::updateFootprint.

◆ invokeInlineRouter()

bool EDIT_TOOL::invokeInlineRouter ( int  aDragMode)
private

Definition at line 200 of file edit_tool.cpp.

201 {
203 
204  if( !theRouter )
205  return false;
206 
207  // don't allow switch from moving to dragging
208  if( m_dragging )
209  {
210  wxBell();
211  return false;
212  }
213 
214  // make sure we don't accidentally invoke inline routing mode while the router is already active!
215  if( theRouter->IsToolActive() )
216  return false;
217 
218  if( theRouter->CanInlineDrag( aDragMode ) )
219  {
221  return true;
222  }
223 
224  return false;
225 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
bool m_dragging
Definition: edit_tool.h:192
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:211
static ROUTER * theRouter
Definition: pns_router.cpp:59

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

Referenced by doMoveSelection(), and Drag().

◆ IsFootprintEditor()

bool PCB_TOOL_BASE::IsFootprintEditor ( ) const
inlineinherited

◆ isInteractiveDragEnabled()

bool EDIT_TOOL::isInteractiveDragEnabled ( ) const
private

Definition at line 228 of file edit_tool.cpp.

229 {
231 
232  return router && router->Router()->Settings().InlineDragEnabled();
233 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
ROUTER * Router() const
ROUTING_SETTINGS & Settings()
Definition: pns_router.h:184

References TOOL_MANAGER::GetTool(), PNS::ROUTING_SETTINGS::InlineDragEnabled(), TOOL_BASE::m_toolMgr, PNS::TOOL_BASE::Router(), and PNS::ROUTER::Settings().

Referenced by doMoveSelection().

◆ isRouterActive()

bool EDIT_TOOL::isRouterActive ( ) const
private

Definition at line 236 of file edit_tool.cpp.

237 {
239 
240  return router && router->IsToolActive();
241 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool IsToolActive() const
Definition: tool_base.cpp:31

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

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

◆ IsToolActive()

bool TOOL_BASE::IsToolActive ( ) const
inherited

Definition at line 31 of file tool_base.cpp.

32 {
33  return m_toolMgr->IsToolActive( m_toolId );
34 }
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
TOOL_ID m_toolId
Name of the tool.
Definition: tool_base.h:210
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 ROUTER_TOOL::handleLayerSwitch(), isRouterActive(), 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 1500 of file edit_tool.cpp.

1501 {
1502  if( isRouterActive() )
1503  {
1504  wxBell();
1505  return 0;
1506  }
1507 
1509  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1510  {
1511  std::set<BOARD_ITEM*> added_items;
1512 
1513  // Iterate from the back so we don't have to worry about removals.
1514  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
1515  {
1516  BOARD_ITEM* item = aCollector[i];
1517 
1518  // We don't operate on pads; convert them to footprint selections
1519  if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T
1520  && !item->GetParent()->IsLocked() )
1521  {
1522  aCollector.Remove( item );
1523 
1524  if( item->GetParent() && !aCollector.HasItem( item->GetParent() ) )
1525  added_items.insert( item->GetParent() );
1526  }
1527  }
1528 
1529  for( BOARD_ITEM* item : added_items )
1530  aCollector.Append( item );
1531 
1532  sTool->FilterCollectorForGroups( aCollector );
1533  },
1534  !m_dragging && !m_isFootprintEditor /* prompt user regarding locked items */ );
1535 
1536  if( selection.Empty() )
1537  return 0;
1538 
1540  auto refPoint = selection.GetReferencePoint();
1541  wxPoint mirrorPoint( refPoint.x, refPoint.y );
1542 
1543  // When editing footprints, all items have the same parent
1544  if( IsFootprintEditor() )
1545  m_commit->Modify( selection.Front() );
1546 
1547  for( EDA_ITEM* item : selection )
1548  {
1549  // only modify items we can mirror
1550  switch( item->Type() )
1551  {
1552  case PCB_FP_SHAPE_T:
1553  case PCB_FP_TEXT_T:
1554  case PCB_FP_ZONE_T:
1555  case PCB_PAD_T:
1556  // Only create undo entry for items on the board
1557  if( !item->IsNew() && !IsFootprintEditor() )
1558  m_commit->Modify( item );
1559 
1560  break;
1561  default:
1562  continue;
1563  }
1564 
1565  // modify each object as necessary
1566  switch( item->Type() )
1567  {
1568  case PCB_FP_SHAPE_T:
1569  {
1570  FP_SHAPE* shape = static_cast<FP_SHAPE*>( item );
1571  shape->Mirror( mirrorPoint, false );
1572  break;
1573  }
1574 
1575  case PCB_FP_ZONE_T:
1576  {
1577  FP_ZONE* zone = static_cast<FP_ZONE*>( item );
1578  zone->Mirror( mirrorPoint, false );
1579  break;
1580  }
1581 
1582  case PCB_FP_TEXT_T:
1583  {
1584  FP_TEXT* text = static_cast<FP_TEXT*>( item );
1585  text->Mirror( mirrorPoint, false );
1586  break;
1587  }
1588 
1589  case PCB_PAD_T:
1590  {
1591  PAD* pad = static_cast<PAD*>( item );
1592  mirrorPadX( *pad, mirrorPoint );
1593  break;
1594  }
1595 
1596  default:
1597  // it's likely the commit object is wrong if you get here
1598  // Unsure if PCB_GROUP_T needs special attention here.
1599  assert( false );
1600  break;
1601  }
1602  }
1603 
1604  if( !m_dragging )
1605  m_commit->Push( _( "Mirror" ) );
1606 
1607  if( selection.IsHover() && !m_dragging )
1609 
1611 
1612  if( m_dragging )
1614 
1615  return 0;
1616 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
VECTOR2I GetReferencePoint() const
Definition: selection.h:259
bool IsHover() const
Definition: selection.h:72
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
static void mirrorPadX(PAD &aPad, const wxPoint &aMirrorPoint)
Mirror a pad in the vertical axis passing through a point (mirror left to right)
Definition: edit_tool.cpp:1478
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:206
bool IsNew() const
Definition: eda_item.h:169
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:105
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
const PCB_SELECTION & selection() const
bool updateModificationPoint(PCB_SELECTION &aSelection)
Definition: edit_tool.cpp:2279
bool m_dragging
Definition: edit_tool.h:192
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
Definition: collector.h:203
bool m_isFootprintEditor
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
virtual bool IsLocked() const
Definition: board_item.h:249
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
void Mirror(const wxPoint &aCentre, bool aMirrorAroundXAxis)
Mirror an edge of the footprint.
Definition: fp_shape.cpp:224
class ZONE, managed by a footprint
Definition: typeinfo.h:94
bool isRouterActive() const
Definition: edit_tool.cpp:236
void Mirror(const wxPoint &aMirrorRef, bool aMirrorLeftRight)
Mirror the outlines relative to a given horizontal axis the layer is not changed.
Definition: zone.cpp:742
The selection tool: currently supports:
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
bool IsFootprintEditor() const
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:460
void FilterCollectorForGroups(GENERAL_COLLECTOR &aCollector) const
Definition: pad.h:60
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
A specialization of ZONE for use in footprints.
Definition: zone.h:943
EDA_ITEM * Front() const
Definition: selection.h:203
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References _, COLLECTOR::Append(), SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForGroups(), SELECTION::Front(), COLLECTOR::GetCount(), BOARD_ITEM::GetParent(), SELECTION::GetReferencePoint(), COLLECTOR::HasItem(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), BOARD_ITEM::IsLocked(), isRouterActive(), m_commit, m_dragging, PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, FP_SHAPE::Mirror(), ZONE::Mirror(), mirrorPadX(), pad, PCB_FP_SHAPE_T, PCB_FP_TEXT_T, PCB_FP_ZONE_T, PCB_PAD_T, TOOL_MANAGER::ProcessEvent(), COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, text, EDA_ITEM::Type(), PCB_ACTIONS::updateLocalRatsnest, and updateModificationPoint().

Referenced by setTransitions().

◆ Move()

int EDIT_TOOL::Move ( const TOOL_EVENT aEvent)

Main loop in which events are handled.

Definition at line 629 of file edit_tool.cpp.

630 {
631  if( isRouterActive() )
632  {
633  wxBell();
634  return 0;
635  }
636 
637  return doMoveSelection( aEvent );
638 }
int doMoveSelection(TOOL_EVENT aEvent, bool aPickReference=false)
Definition: edit_tool.cpp:655
bool isRouterActive() const
Definition: edit_tool.cpp:236

References doMoveSelection(), and isRouterActive().

Referenced by 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 1915 of file edit_tool.cpp.

1916 {
1917  if( isRouterActive() )
1918  {
1919  wxBell();
1920  return 0;
1921  }
1922 
1924  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1925  {
1926  std::set<BOARD_ITEM*> added_items;
1927 
1928  // Iterate from the back so we don't have to worry about removals.
1929  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
1930  {
1931  BOARD_ITEM* item = aCollector[i];
1932 
1933  if( item->Type() == PCB_MARKER_T )
1934  aCollector.Remove( item );
1935 
1936  // We don't operate on pads; convert them to footprint selections
1937  if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T )
1938  {
1939  aCollector.Remove( item );
1940 
1941  if( item->GetParent() && !aCollector.HasItem( item->GetParent() ) )
1942  added_items.insert( item->GetParent() );
1943  }
1944  }
1945 
1946  for( BOARD_ITEM* item : added_items )
1947  aCollector.Append( item );
1948 
1949  sTool->FilterCollectorForGroups( aCollector );
1950  },
1951  !m_isFootprintEditor /* prompt user regarding locked items */ );
1952 
1953  if( selection.Empty() )
1954  return 0;
1955 
1956  wxPoint translation;
1957  double rotation;
1958  ROTATION_ANCHOR rotationAnchor = selection.Size() > 1 ? ROTATE_AROUND_SEL_CENTER
1960 
1961  // TODO: Implement a visible bounding border at the edge
1962  auto sel_box = selection.GetBoundingBox();
1963 
1964  DIALOG_MOVE_EXACT dialog( frame(), translation, rotation, rotationAnchor, sel_box );
1965  int ret = dialog.ShowModal();
1966 
1967  if( ret == wxID_OK )
1968  {
1969  VECTOR2I rp = selection.GetCenter();
1970  wxPoint selCenter( rp.x, rp.y );
1971 
1972  // Make sure the rotation is from the right reference point
1973  selCenter += translation;
1974 
1975  // When editing footprints, all items have the same parent
1976  if( IsFootprintEditor() )
1977  m_commit->Modify( selection.Front() );
1978 
1979  for( EDA_ITEM* selItem : selection )
1980  {
1981  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem );
1982 
1983  if( !item->IsNew() && !IsFootprintEditor() )
1984  {
1985  m_commit->Modify( item );
1986 
1987  if( item->Type() == PCB_GROUP_T )
1988  {
1989  PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
1990 
1991  group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
1992  {
1993  m_commit->Modify( bItem );
1994  });
1995  }
1996  }
1997 
1998  if( !item->GetParent() || !item->GetParent()->IsSelected() )
1999  item->Move( translation );
2000 
2001  switch( rotationAnchor )
2002  {
2004  item->Rotate( item->GetPosition(), rotation );
2005  break;
2007  item->Rotate( selCenter, rotation );
2008  break;
2010  item->Rotate( (wxPoint) frame()->GetScreen()->m_LocalOrigin, rotation );
2011  break;
2013  item->Rotate( board()->GetDesignSettings().m_AuxOrigin, rotation );
2014  break;
2015  }
2016 
2017  if( !m_dragging )
2018  getView()->Update( item );
2019  }
2020 
2021  m_commit->Push( _( "Move exact" ) );
2022 
2023  if( selection.IsHover() )
2025 
2027 
2028  if( m_dragging )
2030  }
2031 
2032  return 0;
2033 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
bool IsHover() const
Definition: selection.h:72
BOARD * board() const
bool IsSelected() const
Definition: eda_item.h:173
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:50
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.h:139
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
virtual wxPoint GetPosition() const
Definition: eda_item.h:302
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:206
bool IsNew() const
Definition: eda_item.h:169
void Append(EDA_ITEM *item)
Add an item to the end of the list.
Definition: collector.h:105
PCB_BASE_EDIT_FRAME * frame() const
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
const PCB_SELECTION & selection() const
bool m_dragging
Definition: edit_tool.h:192
virtual EDA_RECT GetBoundingBox() const
Definition: selection.h:180
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
virtual void Move(const wxPoint &aMoveVector)
Move this object.
Definition: board_item.h:277
bool HasItem(const EDA_ITEM *aItem) const
Tests if aItem has already been collected.
Definition: collector.h:203
virtual void Rotate(const wxPoint &aRotCentre, double aAngle)
Rotate this object.
Definition: board_item.h:294
ROTATION_ANCHOR
bool m_isFootprintEditor
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
class MARKER_PCB, a marker used to show something
Definition: typeinfo.h:98
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
bool isRouterActive() const
Definition: edit_tool.cpp:236
The selection tool: currently supports:
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
bool IsFootprintEditor() const
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:460
void FilterCollectorForGroups(GENERAL_COLLECTOR &aCollector) const
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
EDA_ITEM * Front() const
Definition: selection.h:203
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: view.cpp:1503
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

References _, COLLECTOR::Append(), PCB_TOOL_BASE::board(), SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForGroups(), PCB_TOOL_BASE::frame(), SELECTION::Front(), SELECTION::GetBoundingBox(), SELECTION::GetCenter(), COLLECTOR::GetCount(), BOARD_ITEM::GetParent(), EDA_ITEM::GetPosition(), TOOL_BASE::getView(), group, COLLECTOR::HasItem(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), EDA_ITEM::IsNew(), isRouterActive(), EDA_ITEM::IsSelected(), m_commit, m_dragging, PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, BOARD_ITEM::Move(), PCB_GROUP_T, PCB_MARKER_T, PCB_PAD_T, TOOL_MANAGER::ProcessEvent(), COLLECTOR::Remove(), 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().

◆ MoveWithReference()

int EDIT_TOOL::MoveWithReference ( const TOOL_EVENT aEvent)

Move an item but with a reference point selected first.

Definition at line 641 of file edit_tool.cpp.

642 {
643  if( isRouterActive() )
644  {
645  wxBell();
646  return 0;
647  }
648 
649  return doMoveSelection( aEvent, true );
650 }
int doMoveSelection(TOOL_EVENT aEvent, bool aPickReference=false)
Definition: edit_tool.cpp:655
bool isRouterActive() const
Definition: edit_tool.cpp:236

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 2253 of file edit_tool.cpp.

2255 {
2256  for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2257  {
2258  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
2259 
2260  if( item->Type() != PCB_PAD_T )
2261  aCollector.Remove( i );
2262  }
2263 }
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
class PAD, a pad in a footprint
Definition: typeinfo.h:89
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:115
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:87
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163

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

Definition at line 2302 of file edit_tool.cpp.

2304 {
2306  OPT<VECTOR2I> pickedPoint;
2307  bool done = false;
2308 
2309  m_statusPopup->SetText( aTooltip );
2310 
2311  picker->SetClickHandler(
2312  [&]( const VECTOR2D& aPoint ) -> bool
2313  {
2314  pickedPoint = aPoint;
2315 
2316  if( !aSuccessMessage.empty() )
2317  {
2318  m_statusPopup->SetText( aSuccessMessage );
2319  m_statusPopup->Expire( 800 );
2320  }
2321  else
2322  {
2323  m_statusPopup->Hide();
2324  }
2325 
2326  return false; // we don't need any more points
2327  } );
2328 
2329  picker->SetMotionHandler(
2330  [&]( const VECTOR2D& aPos )
2331  {
2332  m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
2333  } );
2334 
2335  picker->SetCancelHandler(
2336  [&]()
2337  {
2338  if( !aCanceledMessage.empty() )
2339  {
2340  m_statusPopup->SetText( aCanceledMessage );
2341  m_statusPopup->Expire( 800 );
2342  }
2343  else
2344  {
2345  m_statusPopup->Hide();
2346  }
2347  } );
2348 
2349  picker->SetFinalizeHandler(
2350  [&]( const int& aFinalState )
2351  {
2352  done = true;
2353  } );
2354 
2355  m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
2356  m_statusPopup->Popup();
2357 
2358  std::string tool = "";
2359  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
2360 
2361  while( !done )
2362  {
2363  // Pass events unless we receive a null event, then we must shut down
2364  if( TOOL_EVENT* evt = Wait() )
2365  evt->SetPassEvent();
2366  else
2367  break;
2368  }
2369 
2370  // Ensure statusPopup is hidden after use and before deleting it:
2371  m_statusPopup->Hide();
2372 
2373  if( pickedPoint.is_initialized() )
2374  aReferencePoint = pickedPoint.get();
2375 
2376  return pickedPoint.is_initialized();
2377 }
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.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:100
static TOOL_ACTION pickerTool
Definition: actions.h:158
Generic, UI-independent tool event.
Definition: tool_event.h:173
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:80
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup
Definition: edit_tool.h:195
Generic tool for picking an item.
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:69
boost::optional< T > OPT
Definition: optional.h:7
void SetCancelHandler(CANCEL_HANDLER aHandler)
Set a handler for cancel events (ESC or context-menu Cancel).
Definition: picker_tool.h:89

References 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(), 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 1312 of file edit_tool.cpp.

1313 {
1314  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1316  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1317  {
1318  } );
1319 
1320  // Tracks & vias are treated in a special way:
1322  {
1323  DIALOG_TRACK_VIA_PROPERTIES dlg( editFrame, selection, *m_commit );
1324  dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
1325  }
1326  else if( selection.Size() == 1 )
1327  {
1328  // Display properties dialog
1329  BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
1330 
1331  // Do not handle undo buffer, it is done by the properties dialogs
1332  editFrame->OnEditItemRequest( item );
1333 
1334  // Notify other tools of the changes
1336  }
1337  else if( selection.Size() == 0 && getView()->IsLayerVisible( LAYER_DRAWINGSHEET ) )
1338  {
1339  DS_PROXY_VIEW_ITEM* ds = editFrame->GetCanvas()->GetDrawingSheet();
1340  VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1341 
1342  if( ds && ds->HitTestDrawingSheetItems( getView(), (wxPoint) cursorPos ) )
1344  }
1345 
1346  if( selection.IsHover() )
1347  {
1349 
1350  // Notify other tools of the changes -- This updates the visual ratsnest
1352  }
1353 
1354  return 0;
1355 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
bool IsHover() const
Definition: selection.h:72
static const KICAD_T Tracks[]
A scan list for only TRACKs.
Definition: collectors.h:299
static TOOL_ACTION pageSettings
Definition: actions.h:59
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
Create a functor that tests if the selected items are only of given types.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
virtual void OnEditItemRequest(BOARD_ITEM *aItem)=0
Install the corresponding dialog editor for the given item.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
bool HitTestDrawingSheetItems(KIGFX::VIEW *aView, const wxPoint &aPosition)
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:206
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
const PCB_SELECTION & selection() const
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
Common, abstract interface for edit frames.
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
int Size() const
Returns the number of selected parts.
Definition: selection.h:128
The selection tool: currently supports:
drawingsheet frame and titleblock
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
EDA_ITEM * Front() const
Definition: selection.h:203
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:404

References SELECTION::Front(), PCB_BASE_FRAME::GetCanvas(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_DRAW_PANEL_GAL::GetDrawingSheet(), TOOL_BASE::getView(), TOOL_BASE::getViewControls(), 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, TOOL_MANAGER::ProcessEvent(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, DIALOG_SHIM::ShowQuasiModal(), SELECTION::Size(), and GENERAL_COLLECTOR::Tracks.

Referenced by setTransitions().

◆ Remove()

int EDIT_TOOL::Remove ( const TOOL_EVENT aEvent)

Delete currently selected items.

Definition at line 1727 of file edit_tool.cpp.

1728 {
1729  if( isRouterActive() )
1730  {
1731  wxBell();
1732  return 0;
1733  }
1734 
1735  std::vector<BOARD_ITEM*> lockedItems;
1736  Activate();
1737 
1738  // get a copy instead of reference (as we're going to clear the selection before removing items)
1739  PCB_SELECTION selectionCopy;
1742 
1743  // If we are in a "Cut" operation, then the copied selection exists already and we want to
1744  // delete exactly that; no more, no fewer. Any filtering for locked items must be done in
1745  // the copyToClipboard() routine.
1746  if( isCut )
1747  {
1748  selectionCopy = m_selectionTool->GetSelection();
1749  }
1750  else
1751  {
1752  selectionCopy = m_selectionTool->RequestSelection(
1753  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1754  {
1755  },
1756  !m_isFootprintEditor /* prompt user regarding locked items */ );
1757  }
1758 
1759  bool isHover = selectionCopy.IsHover();
1760 
1761  // in "alternative" mode, deletion is not just a simple list of selected items,
1762  // it removes whole tracks, not just segments
1763  if( isAlt && isHover
1764  && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
1765  {
1767  }
1768 
1769  if( selectionCopy.Empty() )
1770  return 0;
1771 
1772  // As we are about to remove items, they have to be removed from the selection first
1774 
1775  for( EDA_ITEM* item : selectionCopy )
1776  {
1777  PCB_GROUP* parentGroup = static_cast<BOARD_ITEM*>( item )->GetParentGroup();
1778 
1779  if( parentGroup )
1780  {
1781  m_commit->Modify( parentGroup );
1782  parentGroup->RemoveItem( static_cast<BOARD_ITEM*>( item ) );
1783  }
1784 
1785  switch( item->Type() )
1786  {
1787  case PCB_FP_TEXT_T:
1788  {
1789  FP_TEXT* text = static_cast<FP_TEXT*>( item );
1790  FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1791 
1792  if( text->GetType() == FP_TEXT::TEXT_is_DIVERS )
1793  {
1794  m_commit->Modify( parent );
1795  getView()->Remove( text );
1796  parent->Remove( text );
1797  }
1798  }
1799  break;
1800 
1801  case PCB_PAD_T:
1802  {
1803  PAD* pad = static_cast<PAD*>( item );
1804  FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1805 
1806  m_commit->Modify( parent );
1807  getView()->Remove( pad );
1808  parent->Remove( pad );
1809  }
1810  break;
1811 
1812  case PCB_FP_ZONE_T:
1813  {
1814  FP_ZONE* zone = static_cast<FP_ZONE*>( item );
1815  FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1816 
1817  m_commit->Modify( parent );
1818  getView()->Remove( zone );
1819  parent->Remove( zone );
1820  }
1821  break;
1822 
1823  case PCB_ZONE_T:
1824  // We process the zones special so that cutouts can be deleted when the delete tool
1825  // is called from inside a cutout when the zone is selected.
1826  {
1827  // Only interact with cutouts when deleting and a single item is selected
1828  if( !isCut && selectionCopy.GetSize() == 1 )
1829  {
1831  ZONE* zone = static_cast<ZONE*>( item );
1832 
1833  int outlineIdx, holeIdx;
1834 
1835  if( zone->HitTestCutout( curPos, &outlineIdx, &holeIdx ) )
1836  {
1837  // Remove the cutout
1838  m_commit->Modify( zone );
1839  zone->RemoveCutout( outlineIdx, holeIdx );
1840  zone->UnFill();
1841  // TODO Refill zone when KiCad supports auto re-fill
1842 
1843  // Update the display
1844  zone->HatchBorder();
1845  canvas()->Refresh();
1846 
1847  // Restore the selection on the original zone
1849 
1850  break;
1851  }
1852  }
1853 
1854  // Remove the entire zone otherwise
1855  m_commit->Remove( item );
1856  }
1857  break;
1858 
1859  case PCB_GROUP_T:
1860  {
1861  PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
1862 
1863  auto removeItem = [&]( BOARD_ITEM* bItem )
1864  {
1865  if( bItem->GetParent() && bItem->GetParent()->Type() == PCB_FOOTPRINT_T )
1866  {
1867  // Silently ignore delete of Reference or Value if they happen to be in
1868  // group.
1869  if( bItem->Type() == PCB_FP_TEXT_T )
1870  {
1871  if( static_cast<FP_TEXT*>( bItem )->GetType() != FP_TEXT::TEXT_is_DIVERS )
1872  return;
1873  }
1874 
1875  m_commit->Modify( bItem->GetParent() );
1876  getView()->Remove( bItem );
1877  bItem->GetParent()->Remove( bItem );
1878  }
1879  else
1880  {
1881  m_commit->Remove( bItem );
1882  }
1883  };
1884 
1885  removeItem( group );
1886 
1887  group->RunOnDescendants( [&]( BOARD_ITEM* aDescendant )
1888  {
1889  removeItem( aDescendant );
1890  });
1891  }
1892  break;
1893 
1894  default:
1895  m_commit->Remove( item );
1896  break;
1897  }
1898  }
1899 
1900  // If the entered group has been emptied then leave it.
1901  PCB_GROUP* enteredGroup = m_selectionTool->GetEnteredGroup();
1902 
1903  if( enteredGroup && enteredGroup->GetItems().empty() )
1905 
1906  if( isCut )
1907  m_commit->Push( _( "Cut" ) );
1908  else
1909  m_commit->Push( _( "Delete" ) );
1910 
1911  return 0;
1912 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:93
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
Definition: zone.cpp:787
bool IsHover() const
Definition: selection.h:72
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
REMOVE_FLAGS
Definition: actions.h:191
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
Definition: selection.h:233
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:108
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:50
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:352
void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: footprint.cpp:521
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
static TOOL_ACTION selectConnection
Select tracks between junctions or expands an existing selection to pads or the entire connection.
Definition: pcb_actions.h:78
class PAD, a pad in a footprint
Definition: typeinfo.h:89
PCB_GROUP * GetEnteredGroup()
Apply the SELECTION_FILTER_OPTIONS to a collection of items.
PCB_SELECTION_TOOL * m_selectionTool
Definition: edit_tool.h:190
std::unordered_set< BOARD_ITEM * > & GetItems()
Definition: pcb_group.h:68
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
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:519
PCB_SELECTION & GetSelection()
Return the set of currently selected items.
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
Definition: zone.cpp:924
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:443
bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
Definition: pcb_group.cpp:50
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
class ZONE, a copper pour area
Definition: typeinfo.h:105
void ExitGroup(bool aSelectGroup=false)
Leave the currently entered group.
bool m_isFootprintEditor
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:122
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection set, filtered according to aFlags and aClientFilter.
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:241
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition: pcb_actions.h:66
class ZONE, managed by a footprint
Definition: typeinfo.h:94
bool isRouterActive() const
Definition: edit_tool.cpp:236
The selection tool: currently supports:
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:150
void Activate()
Run the tool.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
Definition: pad.h:60
bool UnFill()
Removes the zone filling.
Definition: zone.cpp:186
PCB_DRAW_PANEL_GAL * canvas() const
A specialization of ZONE for use in footprints.
Definition: zone.h:943
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.

References _, TOOL_INTERACTIVE::Activate(), ACTIONS::ALT, PCB_TOOL_BASE::canvas(), ACTIONS::CUT, SELECTION::Empty(), PCB_SELECTION_TOOL::ExitGroup(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_SELECTION_TOOL::GetEnteredGroup(), PCB_GROUP::GetItems(), BOARD_ITEM::GetParentGroup(), PCB_SELECTION_TOOL::GetSelection(), TOOL_BASE::getView(), TOOL_BASE::getViewControls(), group, SELECTION::HasType(), ZONE::HatchBorder(), ZONE::HitTestCutout(), SELECTION::IsHover(), isRouterActive(), m_commit, PCB_TOOL_BASE::m_isFootprintEditor, m_selectionTool, TOOL_BASE::m_toolMgr, pad, TOOL_EVENT::Parameter(), PCB_FOOTPRINT_T, PCB_FP_TEXT_T, PCB_FP_ZONE_T, PCB_GROUP_T, PCB_PAD_T, PCB_TRACE_T, PCB_VIA_T, PCB_ZONE_T, EDA_DRAW_PANEL_GAL::Refresh(), KIGFX::VIEW::Remove(), FOOTPRINT::Remove(), ZONE::RemoveCutout(), PCB_GROUP::RemoveItem(), PCB_SELECTION_TOOL::RequestSelection(), TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectConnection, PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItem, text, FP_TEXT::TEXT_is_DIVERS, and ZONE::UnFill().

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 77 of file edit_tool.cpp.

78 {
79  m_dragging = false;
80 
81  m_statusPopup = std::make_unique<STATUS_TEXT_POPUP>( getEditFrame<PCB_BASE_EDIT_FRAME>() );
82 
83  if( aReason != RUN )
84  m_commit.reset( new BOARD_COMMIT( this ) );
85 }
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:191
Tool is invoked after being inactive.
Definition: tool_base.h:80
bool m_dragging
Definition: edit_tool.h:192
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup
Definition: edit_tool.h:195

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

◆ Rotate()

int EDIT_TOOL::Rotate ( const TOOL_EVENT aEvent)

Rotate currently selected items.

Definition at line 1358 of file edit_tool.cpp.

1359 {
1360  if( isRouterActive() )
1361  {
1362  wxBell();
1363  return 0;
1364  }
1365 
1366  PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1367 
1369  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1370  {
1371  std::set<BOARD_ITEM*> added_items;
1372 
1373  // Iterate from the back so we don't have to worry about removals.
1374  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
1375  {
1376  BOARD_ITEM* item = aCollector[i];
1377 
1378  // We don't operate on pads; convert them to footprint selections
1379  if( !sTool->IsFootprintEditor() && item->Type() == PCB_PAD_T
1380  && !item->GetParent()->IsLocked() )
1381  {
1382  aCollector.Remove( item );
1383 
1384  if( item->GetParent() && !aCollector.HasItem( item->GetParent() ) )
1385  added_items.insert( item->GetParent() );
1386  }
1387 
1388  // We can't rotate both a footprint and its text in the same operation, so if
1389  // both are selected, remove the text
1390  if( item->Type() == PCB_FP_TEXT_T && aCollector.HasItem( item->GetParent() ) )
1391  aCollector.Remove( item );
1392  }
1393 
1394  for( BOARD_ITEM* item : added_items )
1395  aCollector.Append( item );
1396 
1397  sTool->FilterCollectorForGroups( aCollector );
1398  },
1399  !m_dragging && !m_isFootprintEditor /* prompt user regarding locked items */ );
1400 
1401  if( selection.Empty() )
1402  return 0;
1403 
1404  OPT<VECTOR2I> oldRefPt = boost::make_optional<VECTOR2I>( false, VECTOR2I( 0, 0 ) );
1405 
1407  oldRefPt = selection.GetReferencePoint();
1408 
1410 
1412  const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
1413 
1414  // When editing footprints, all items have the same parent
1415  if( IsFootprintEditor() )
1416  m_commit->Modify( selection.Front() );
1417 
1418  for( EDA_ITEM* item : selection )
1419  {