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 , REDRAW }
 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 &aTrack)
 Drag-resize an arc (and change end points of connected straight segments). More...
 
int Properties (const TOOL_EVENT &aEvent)
 Display properties window for the selected object. More...
 
int Rotate (const TOOL_EVENT &aEvent)
 Rotate currently selected items. More...
 
int Flip (const TOOL_EVENT &aEvent)
 Rotate currently selected items. More...
 
int Mirror (const TOOL_EVENT &aEvent)
 Mirror the current selection. More...
 
int Swap (const TOOL_EVENT &aEvent)
 Swap currently selected items' positions. More...
 
int PackAndMoveFootprints (const TOOL_EVENT &aEvent)
 Try to fit selected footprints inside a minimal area and start movement. More...
 
int ChangeTrackWidth (const TOOL_EVENT &aEvent)
 
int FilletTracks (const TOOL_EVENT &aEvent)
 Fillet (i.e. More...
 
int FilletLines (const TOOL_EVENT &aEvent)
 Fillet (i.e. More...
 
int Remove (const TOOL_EVENT &aEvent)
 Delete currently selected items. More...
 
void DeleteItems (const PCB_SELECTION &aItems, bool aIsCut)
 
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 CreateArray (const TOOL_EVENT &aEvent)
 Create an array of the selected items, invoking the array editor dialog to set the options. More...
 
BOARD_COMMITGetCurrentCommit () const
 
void SetIsFootprintEditor (bool aEnabled)
 Function SetIsFootprintEditor() More...
 
bool IsFootprintEditor () const
 
void SetIsBoardEditor (bool aEnabled)
 
bool IsBoardEditor () const
 
virtual bool Is45Limited () const
 Should the tool use its 45° mode option? More...
 
void Activate ()
 Run the tool. More...
 
TOOL_MENUGetToolMenu ()
 
void SetContextMenu (ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
 Assign a context menu and tells when it should be activated. More...
 
void RunMainStack (std::function< void()> aFunc)
 Call a function using the main stack. More...
 
template<class T >
void Go (int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
 Define which state (aStateFunc) to go when a certain event arrives (aConditions). More...
 
TOOL_EVENTWait (const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
 Suspend execution of the tool until an event specified in aEventList arrives. More...
 
TOOL_TYPE GetType () const
 Return the type of the tool. More...
 
TOOL_ID GetId () const
 Return the unique identifier of the tool. More...
 
const std::string & GetName () const
 Return the name of the tool. More...
 
TOOL_MANAGERGetManager () const
 Return the instance of TOOL_MANAGER that takes care of the tool. More...
 
bool IsToolActive () const
 

Static Public Member Functions

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

Static Public Attributes

static const std::vector< KICAD_TMirrorableItems
 

Protected Types

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

Protected Member Functions

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

Protected Attributes

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

Private Member Functions

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

Private Attributes

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

Static Private Attributes

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

Detailed Description

The interactive edit tool.

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

Definition at line 64 of file edit_tool.h.

Member Enumeration Documentation

◆ INTERACTIVE_PLACEMENT_OPTIONS

Options for placing items interactively.

Enumerator
IPO_ROTATE 

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

IPO_FLIP 

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

IPO_SINGLE_CLICK 

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

IPO_REPEAT 

Allow repeat placement of the item.

Definition at line 121 of file pcb_tool_base.h.

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

◆ RESET_REASON

enum TOOL_BASE::RESET_REASON
inherited

Determine the reason of reset for a tool.

Enumerator
RUN 

Tool is invoked after being inactive.

MODEL_RELOAD 

Model changes (required full reload)

GAL_SWITCH 

Rendering engine changes.

REDRAW 

Full drawing refresh.

Definition at line 77 of file tool_base.h.

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

Constructor & Destructor Documentation

◆ EDIT_TOOL()

EDIT_TOOL::EDIT_TOOL ( )

Definition at line 73 of file edit_tool.cpp.

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

Member Function Documentation

◆ Activate()

void TOOL_INTERACTIVE::Activate ( )
inherited

Run the tool.

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

Definition at line 51 of file tool_interactive.cpp.

52{
54}
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h: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(), SCH_EDIT_TOOL::DeleteItemCursor(), SYMBOL_EDITOR_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), PCB_CONTROL::DeleteItemCursor(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), PCB_TOOL_BASE::doInteractiveItemPlacement(), doMoveSelection(), DragArcTrack(), DRAWING_TOOL::DrawArc(), DRAWING_TOOL::DrawCircle(), DRAWING_TOOL::DrawDimension(), DRAWING_TOOL::DrawLine(), MICROWAVE_TOOL::drawMicrowaveInductor(), DRAWING_TOOL::DrawRectangle(), SCH_DRAWING_TOOLS::DrawShape(), SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), SCH_DRAWING_TOOLS::DrawSheet(), DRAWING_TOOL::DrawZone(), BOARD_EDITOR_CONTROL::DrillOrigin(), PAD_TOOL::EnumeratePads(), PCB_CONTROL::GridSetOrigin(), SCH_EDITOR_CONTROL::HighlightNetCursor(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), DRAWING_TOOL::InteractivePlaceWithPreview(), BOARD_INSPECTION_TOOL::LocalRatsnestTool(), EE_POINT_EDITOR::Main(), SCH_MOVE_TOOL::Main(), SYMBOL_EDITOR_MOVE_TOOL::Main(), PICKER_TOOL::Main(), PL_EDIT_TOOL::Main(), PL_POINT_EDITOR::Main(), PCB_PICKER_TOOL::Main(), LENGTH_TUNER_TOOL::MainLoop(), ROUTER_TOOL::MainLoop(), GERBVIEW_INSPECTION_TOOL::MeasureTool(), PCB_VIEWER_TOOLS::MeasureTool(), PCB_POINT_EDITOR::OnSelectionChange(), GROUP_TOOL::PickNewMember(), SYMBOL_EDITOR_DRAWING_TOOLS::PlaceAnchor(), BOARD_EDITOR_CONTROL::PlaceFootprint(), SCH_DRAWING_TOOLS::PlaceImage(), DRAWING_TOOL::PlaceImage(), DRAWING_TOOL::PlaceImportedGraphics(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), DRAWING_TOOL::PlaceText(), Remove(), ROUTER_TOOL::RouteSelected(), POSITION_RELATIVE_TOOL::SelectPositionRelativeItem(), DRAWING_TOOL::SetAnchor(), DRC_TOOL::ShowDRCDialog(), SCH_DRAWING_TOOLS::SingleClickPlace(), SCH_DRAWING_TOOLS::TwoClickPlace(), SYMBOL_EDITOR_DRAWING_TOOLS::TwoClickPlace(), and SCH_LINE_WIRE_BUS_TOOL::UnfoldBus().

◆ attachManager()

void TOOL_BASE::attachManager ( TOOL_MANAGER aManager)
protectedinherited

Set the TOOL_MANAGER the tool will belong to.

Called by TOOL_MANAGER::RegisterTool()

Definition at line 60 of file tool_base.cpp.

61{
62 m_toolMgr = aManager;
63}

References TOOL_BASE::m_toolMgr.

Referenced by TOOL_MANAGER::RegisterTool().

◆ board()

BOARD * PCB_TOOL_BASE::board ( ) const
inlineprotectedinherited

Definition at line 170 of file pcb_tool_base.h.

170{ return getModel<BOARD>(); }

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

◆ canvas()

◆ ChangeTrackWidth()

int EDIT_TOOL::ChangeTrackWidth ( const TOOL_EVENT aEvent)

Definition at line 784 of file edit_tool.cpp.

785{
787 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
788 {
789 // Iterate from the back so we don't have to worry about removals.
790 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
791 {
792 BOARD_ITEM* item = aCollector[ i ];
793
794 if( !dynamic_cast<PCB_TRACK*>( item ) )
795 aCollector.Remove( item );
796 }
797 },
798 true /* prompt user regarding locked items */ );
799
800 for( EDA_ITEM* item : selection )
801 {
802 if( item->Type() == PCB_VIA_T )
803 {
804 PCB_VIA* via = static_cast<PCB_VIA*>( item );
805
806 m_commit->Modify( via );
807
808 int new_width;
809 int new_drill;
810
811 if( via->GetViaType() == VIATYPE::MICROVIA )
812 {
813 NETCLASS* netClass = via->GetEffectiveNetClass();
814
815 new_width = netClass->GetuViaDiameter();
816 new_drill = netClass->GetuViaDrill();
817 }
818 else
819 {
820 new_width = board()->GetDesignSettings().GetCurrentViaSize();
821 new_drill = board()->GetDesignSettings().GetCurrentViaDrill();
822 }
823
824 via->SetDrill( new_drill );
825 via->SetWidth( new_width );
826 }
827 else if( item->Type() == PCB_TRACE_T || item->Type() == PCB_ARC_T )
828 {
829 PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item );
830
831 wxCHECK( track, 0 );
832
833 m_commit->Modify( track );
834
835 int new_width = board()->GetDesignSettings().GetCurrentTrackWidth();
836 track->SetWidth( new_width );
837 }
838 }
839
840 m_commit->Push( _( "Edit track width/via size" ) );
841
842 if( selection.IsHover() )
843 {
845
846 // Notify other tools of the changes -- This updates the visual ratsnest
848 }
849
850 return 0;
851}
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:704
int GetCount() const
Return the number of objects in the list.
Definition: collector.h:81
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
std::unique_ptr< BOARD_COMMIT > m_commit
Definition: edit_tool.h:210
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
Definition: actions.h:214
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:204
A collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:47
int GetuViaDrill() const
Definition: netclass.h:92
int GetuViaDiameter() const
Definition: netclass.h:88
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:59
The selection tool: currently supports:
PCB_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, bool aConfirmLockedItems=false)
Return the current selection, filtered according to aClientFilter.
BOARD * board() const
const PCB_SELECTION & selection() const
void SetWidth(int aWidth)
Definition: pcb_track.h:107
bool IsHover() const
Definition: selection.h:83
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagate an event to tools that requested events of matching type(s).
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:142
#define _(s)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:103
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:101

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

Referenced by setTransitions().

◆ controls()

◆ copyToClipboard()

int EDIT_TOOL::copyToClipboard ( const TOOL_EVENT aEvent)
private

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

Definition at line 2497 of file edit_tool.cpp.

2498{
2499 CLIPBOARD_IO io;
2501 getEditFrame<PCB_BASE_EDIT_FRAME>()->GetMagneticItemsSettings() );
2502 TOOL_EVENT selectReferencePoint( aEvent.Category(), aEvent.Action(),
2503 "pcbnew.InteractiveEdit.selectReferencePoint",
2505
2506 frame()->PushTool( selectReferencePoint );
2507 Activate();
2508
2510 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2511 {
2512 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
2513 {
2514 BOARD_ITEM* item = aCollector[i];
2515
2516 // We can't copy both a footprint and its text in the same operation, so if
2517 // both are selected, remove the text
2518 if( item->Type() == PCB_FP_TEXT_T && aCollector.HasItem( item->GetParent() ) )
2519 aCollector.Remove( item );
2520 }
2521 },
2522
2523 // Prompt user regarding locked items.
2524 aEvent.IsAction( &ACTIONS::cut ) && !m_isFootprintEditor );
2525
2526 if( !selection.Empty() )
2527 {
2528 std::vector<BOARD_ITEM*> items;
2529
2530 for( EDA_ITEM* item : selection )
2531 items.push_back( static_cast<BOARD_ITEM*>( item ) );
2532
2533 VECTOR2I refPoint;
2534
2536 {
2537 if( !pickReferencePoint( _( "Select reference point for the copy..." ),
2538 _( "Selection copied" ),
2539 _( "Copy canceled" ),
2540 refPoint ) )
2541 {
2542 frame()->PopTool( selectReferencePoint );
2543 return 0;
2544 }
2545 }
2546 else
2547 {
2548 refPoint = grid.BestDragOrigin( getViewControls()->GetCursorPosition(), items );
2549 }
2550
2551 selection.SetReferencePoint( refPoint );
2552
2553 io.SetBoard( board() );
2555 frame()->SetStatusText( _( "Selection copied" ) );
2556 }
2557
2558 frame()->PopTool( selectReferencePoint );
2559
2560 if( selection.IsHover() )
2562
2563 return 0;
2564}
static TOOL_ACTION cut
Definition: actions.h:67
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:70
void SaveSelection(const PCB_SELECTION &selected, bool isFootprintEditor)
void SetBoard(BOARD *aBoard)
bool pickReferencePoint(const wxString &aTooltip, const wxString &aSuccessMessage, const wxString &aCanceledMessage, VECTOR2I &aReferencePoint)
Rebuilds the ratsnest for operations that require it outside the commit rebuild.
Definition: edit_tool.cpp:2415
static TOOL_ACTION copyWithReference
copy command with manual reference point selection
Definition: pcb_actions.h:119
int ClearSelection(const TOOL_EVENT &aEvent)
bool m_isFootprintEditor
void SetReferencePoint(const VECTOR2I &aP)
Definition: selection.h:260
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:109
virtual void PopTool(const TOOL_EVENT &aEvent)
Pops a tool from the stack.
virtual void PushTool(const TOOL_EVENT &aEvent)
NB: the definition of "tool" is different at the user level.
Generic, UI-independent tool event.
Definition: tool_event.h:156
TOOL_ACTIONS Action() const
These give a tool a method of informing the TOOL_MANAGER that a particular event should be passed on ...
Definition: tool_event.h:233
TOOL_EVENT_CATEGORY Category() const
Returns more specific information about the type of an event.
Definition: tool_event.h:230
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:81
void Activate()
Run the tool.
@ AS_GLOBAL
Global action (toolbar/main menu event, global shortcut)
Definition: tool_action.h:45

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

Referenced by cutToClipboard(), and setTransitions().

◆ CreateArray()

int EDIT_TOOL::CreateArray ( const TOOL_EVENT aEvent)

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

Definition at line 2334 of file edit_tool.cpp.

2335{
2336 if( isRouterActive() )
2337 {
2338 wxBell();
2339 return 0;
2340 }
2341
2342 // Be sure that there is at least one item that we can modify
2344 []( const VECTOR2I&, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2345 {
2346 sTool->FilterCollectorForMarkers( aCollector );
2347 sTool->FilterCollectorForHierarchy( aCollector, true );
2348 } );
2349
2350 if( selection.Empty() )
2351 return 0;
2352
2353 // we have a selection to work on now, so start the tool process
2354 PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
2355 ARRAY_CREATOR array_creator( *editFrame, m_isFootprintEditor, selection, m_toolMgr );
2356 array_creator.Invoke();
2357
2358 return 0;
2359}
bool isRouterActive() const
Definition: edit_tool.cpp:327
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
void FilterCollectorForMarkers(GENERAL_COLLECTOR &aCollector) const
Drop any PCB_MARKERs from the collector.
void FilterCollectorForHierarchy(GENERAL_COLLECTOR &aCollector, bool aMultiselect) const
In general we don't want to select both a parent and any of it's children.

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

Referenced by setTransitions().

◆ cutToClipboard()

int EDIT_TOOL::cutToClipboard ( const TOOL_EVENT aEvent)
private

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

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

Definition at line 2567 of file edit_tool.cpp.

2568{
2569 if( !copyToClipboard( aEvent ) )
2570 {
2571 // N.B. Setting the CUT flag prevents lock filtering as we only want to delete the items
2572 // that were copied to the clipboard, no more, no fewer. Filtering for locked item, if
2573 // any will be done in the copyToClipboard() routine
2574 TOOL_EVENT evt = aEvent;
2576 Remove( evt );
2577 }
2578
2579 return 0;
2580}
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:2497
int Remove(const TOOL_EVENT &aEvent)
Delete currently selected items.
Definition: edit_tool.cpp:2009
void SetParameter(T aParam)
Set a non-standard parameter assigned to the event.
Definition: tool_event.h:460

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

Referenced by setTransitions().

◆ DeleteItems()

void EDIT_TOOL::DeleteItems ( const PCB_SELECTION aItems,
bool  aIsCut 
)

Definition at line 1814 of file edit_tool.cpp.

1815{
1816 // As we are about to remove items, they have to be removed from the selection first
1818
1819 for( EDA_ITEM* item : aItems )
1820 {
1821 PCB_GROUP* parentGroup = static_cast<BOARD_ITEM*>( item )->GetParentGroup();
1822
1823 if( parentGroup )
1824 {
1825 m_commit->Modify( parentGroup );
1826 parentGroup->RemoveItem( static_cast<BOARD_ITEM*>( item ) );
1827 }
1828
1829 switch( item->Type() )
1830 {
1831 case PCB_FP_TEXT_T:
1832 {
1833 FP_TEXT* text = static_cast<FP_TEXT*>( item );
1834 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1835
1836 switch( text->GetType() )
1837 {
1840 m_commit->Modify( parent );
1841 text->SetVisible( false );
1842 getView()->Update( text );
1843 break;
1845 m_commit->Modify( parent );
1846 getView()->Remove( text );
1847 parent->Remove( text );
1848 break;
1849 default:
1850 wxFAIL; // Shouldn't get here
1851 break;
1852 }
1853
1854 break;
1855 }
1856
1857 case PCB_FP_TEXTBOX_T:
1858 {
1859 FP_TEXTBOX* textbox = static_cast<FP_TEXTBOX*>( item );
1860 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1861
1862 m_commit->Modify( parent );
1863 getView()->Remove( textbox );
1864 parent->Remove( textbox );
1865 break;
1866 }
1867
1868 case PCB_BITMAP_T:
1869 if( IsFootprintEditor() )
1870 {
1871 PCB_BITMAP* fp_bitmap = static_cast<PCB_BITMAP*>( item );
1872 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1873
1874 m_commit->Modify( parent );
1875 getView()->Remove( fp_bitmap );
1876 parent->Remove( fp_bitmap );
1877 }
1878 else
1879 m_commit->Remove( item );
1880
1881 break;
1882
1883 case PCB_PAD_T:
1884 if( IsFootprintEditor() || frame()->GetPcbNewSettings()->m_AllowFreePads )
1885 {
1886 PAD* pad = static_cast<PAD*>( item );
1887 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1888
1889 m_commit->Modify( parent );
1890 getView()->Remove( pad );
1891 parent->Remove( pad );
1892 }
1893
1894 break;
1895
1896 case PCB_FP_ZONE_T:
1897 {
1898 FP_ZONE* zone = static_cast<FP_ZONE*>( item );
1899 FOOTPRINT* parent = static_cast<FOOTPRINT*>( item->GetParent() );
1900
1901 m_commit->Modify( parent );
1902 getView()->Remove( zone );
1903 parent->Remove( zone );
1904 break;
1905 }
1906
1907 case PCB_ZONE_T:
1908 // We process the zones special so that cutouts can be deleted when the delete tool
1909 // is called from inside a cutout when the zone is selected.
1910 {
1911 // Only interact with cutouts when deleting and a single item is selected
1912 if( !aIsCut && aItems.GetSize() == 1 )
1913 {
1915 ZONE* zone = static_cast<ZONE*>( item );
1916
1917 int outlineIdx, holeIdx;
1918
1919 if( zone->HitTestCutout( curPos, &outlineIdx, &holeIdx ) )
1920 {
1921 // Remove the cutout
1922 m_commit->Modify( zone );
1923 zone->RemoveCutout( outlineIdx, holeIdx );
1924 zone->UnFill();
1925
1926 // TODO Refill zone when KiCad supports auto re-fill
1927
1928 // Update the display
1929 zone->HatchBorder();
1930 canvas()->Refresh();
1931
1932 // Restore the selection on the original zone
1934
1935 break;
1936 }
1937 }
1938
1939 // Remove the entire zone otherwise
1940 m_commit->Remove( item );
1941 break;
1942 }
1943
1944 case PCB_GROUP_T:
1945 {
1946 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
1947
1948 auto removeItem =
1949 [&]( BOARD_ITEM* bItem )
1950 {
1951 if( bItem->GetParent() && bItem->GetParent()->Type() == PCB_FOOTPRINT_T )
1952 {
1953 // Silently ignore delete of Reference or Value if they happen to be
1954 // in group.
1955 if( bItem->Type() == PCB_FP_TEXT_T )
1956 {
1957 FP_TEXT* textItem = static_cast<FP_TEXT*>( bItem );
1958
1959 if( textItem->GetType() != FP_TEXT::TEXT_is_DIVERS )
1960 return;
1961 }
1962 else if( bItem->Type() == PCB_PAD_T )
1963 {
1964 if( !IsFootprintEditor()
1966 {
1967 return;
1968 }
1969 }
1970
1971 m_commit->Modify( bItem->GetParent() );
1972 getView()->Remove( bItem );
1973 bItem->GetParent()->Remove( bItem );
1974 }
1975 else
1976 {
1977 m_commit->Remove( bItem );
1978 }
1979 };
1980
1981 removeItem( group );
1982
1983 group->RunOnDescendants( [&]( BOARD_ITEM* aDescendant )
1984 {
1985 removeItem( aDescendant );
1986 });
1987 break;
1988 }
1989
1990 default:
1991 m_commit->Remove( item );
1992 break;
1993 }
1994 }
1995
1996 // If the entered group has been emptied then leave it.
1997 PCB_GROUP* enteredGroup = m_selectionTool->GetEnteredGroup();
1998
1999 if( enteredGroup && enteredGroup->GetItems().empty() )
2001
2002 if( aIsCut )
2003 m_commit->Push( _( "Cut" ) );
2004 else
2005 m_commit->Push( _( "Delete" ) );
2006}
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
void Remove(BOARD_ITEM *aItem, REMOVE_MODE aMode=REMOVE_MODE::NORMAL) override
Removes an item from the container.
Definition: footprint.cpp:628
@ TEXT_is_REFERENCE
Definition: fp_text.h:49
@ TEXT_is_DIVERS
Definition: fp_text.h:51
@ TEXT_is_VALUE
Definition: fp_text.h:50
TEXT_TYPE GetType() const
Definition: fp_text.h:120
A specialization of ZONE for use in footprints.
Definition: zone.h:916
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp:349
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:1591
Definition: pad.h:60
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition: pcb_actions.h:62
PCBNEW_SETTINGS * GetPcbNewSettings() const
Object to handle a bitmap image that can be inserted in a PCB.
Definition: pcb_bitmap.h:42
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:51
std::unordered_set< BOARD_ITEM * > & GetItems()
Definition: pcb_group.h:68
bool RemoveItem(BOARD_ITEM *aItem)
Remove item from group.
Definition: pcb_group.cpp:95
PCB_GROUP * GetEnteredGroup()
void ExitGroup(bool aSelectGroup=false)
Leave the currently-entered group.
bool IsFootprintEditor() const
PCB_DRAW_PANEL_GAL * canvas() const
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
bool UnFill()
Removes the zone filling.
Definition: zone.cpp:215
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:502
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
Definition: zone.cpp:861
void RemoveCutout(int aOutlineIdx, int aHoleIdx)
Remove a cutout from the zone.
Definition: zone.cpp:720
@ PCB_FP_TEXTBOX_T
class FP_TEXTBOX, wrapped text in a footprint
Definition: typeinfo.h:93
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
Definition: typeinfo.h:115
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition: typeinfo.h:112
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_FP_ZONE_T
class ZONE, managed by a footprint
Definition: typeinfo.h:100
@ PCB_BITMAP_T
class PCB_BITMAP, bitmap on a layer
Definition: typeinfo.h:89
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92

References _, PCB_TOOL_BASE::canvas(), PCB_SELECTION_TOOL::ExitGroup(), PCB_TOOL_BASE::frame(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_SELECTION_TOOL::GetEnteredGroup(), PCB_GROUP::GetItems(), PCB_BASE_FRAME::GetPcbNewSettings(), SELECTION::GetSize(), FP_TEXT::GetType(), TOOL_BASE::getView(), TOOL_BASE::getViewControls(), group, ZONE::HatchBorder(), ZONE::HitTestCutout(), PCB_TOOL_BASE::IsFootprintEditor(), PCBNEW_SETTINGS::m_AllowFreePads, m_commit, m_selectionTool, TOOL_BASE::m_toolMgr, pad, PCB_BITMAP_T, PCB_FOOTPRINT_T, PCB_FP_TEXT_T, PCB_FP_TEXTBOX_T, PCB_FP_ZONE_T, PCB_GROUP_T, PCB_PAD_T, PCB_ZONE_T, EDA_DRAW_PANEL_GAL::Refresh(), FOOTPRINT::Remove(), KIGFX::VIEW::Remove(), ZONE::RemoveCutout(), PCB_GROUP::RemoveItem(), TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItem, text, FP_TEXT::TEXT_is_DIVERS, FP_TEXT::TEXT_is_REFERENCE, FP_TEXT::TEXT_is_VALUE, ZONE::UnFill(), and KIGFX::VIEW::Update().

Referenced by PCB_CONTROL::DeleteItemCursor(), and Remove().

◆ displayOptions()

◆ doInteractiveItemPlacement()

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

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

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

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

Definition at line 41 of file pcb_tool_base.cpp.

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

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

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

◆ doMoveSelection()

int EDIT_TOOL::doMoveSelection ( const TOOL_EVENT aEvent,
const wxString &  aCommitMessage 
)
private

Definition at line 279 of file edit_tool_move_fct.cpp.

280{
281 bool moveWithReference = aEvent.IsAction( &PCB_ACTIONS::moveWithReference );
282 bool moveIndividually = aEvent.IsAction( &PCB_ACTIONS::moveIndividually );
283
284 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
285 PCBNEW_SETTINGS* cfg = editFrame->GetPcbNewSettings();
286 BOARD* board = editFrame->GetBoard();
288 VECTOR2I originalCursorPos = controls->GetCursorPosition();
289 STATUS_TEXT_POPUP statusPopup( frame() );
290 wxString status;
291 size_t itemIdx = 0;
292
293 editFrame->PushTool( aEvent );
294
295 // Be sure that there is at least one item that we can modify. If nothing was selected before,
296 // try looking for the stuff under mouse cursor (i.e. KiCad old-style hover selection)
298 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
299 {
300 sTool->FilterCollectorForMarkers( aCollector );
301 sTool->FilterCollectorForHierarchy( aCollector, true );
302 },
303 // Prompt user regarding locked items if in board editor and in free-pad-mode (if
304 // we're not in free-pad mode we delay this until the second RequestSelection()).
306
307 if( m_dragging || selection.Empty() )
308 {
309 editFrame->PopTool( aEvent );
310 return 0;
311 }
312
313 LSET item_layers = selection.GetSelectionLayers();
314 bool is_hover = selection.IsHover(); // N.B. This must be saved before the second call
315 // to RequestSelection() below
316 VECTOR2I pickedReferencePoint;
317
318 // Now filter out pads if not in free pads mode. We cannot do this in the first
319 // RequestSelection() as we need the item_layers when a pad is the selection front.
321 {
323 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
324 {
325 sTool->FilterCollectorForMarkers( aCollector );
326 sTool->FilterCollectorForHierarchy( aCollector, true );
327 sTool->FilterCollectorForFreePads( aCollector );
328 },
329 true /* prompt user regarding locked items */ );
330 }
331
332 if( selection.Empty() )
333 {
334 editFrame->PopTool( aEvent );
335 return 0;
336 }
337
338 Activate();
339 // Must be done after Activate() so that it gets set into the correct context
340 controls->ShowCursor( true );
341 controls->SetAutoPan( true );
343
344 auto displayConstraintsMessage =
345 [editFrame]( bool constrained )
346 {
347 editFrame->DisplayConstraintsMsg( constrained ? _( "Constrain to H, V, 45" )
348 : wxString( wxT( "" ) ) );
349 };
350
351 auto updateStatusPopup =
352 [&]( EDA_ITEM* item, size_t ii, size_t count )
353 {
354 wxString popuptext = _( "Click to place %s (item %ld of %ld)\n"
355 "Press <esc> to cancel all; double-click to finish" );
356 wxString msg;
357
358 if( item->Type() == PCB_FOOTPRINT_T )
359 {
360 FOOTPRINT* fp = static_cast<FOOTPRINT*>( item );
361 msg = fp->GetReference();
362 }
363 else if( item->Type() == PCB_PAD_T )
364 {
365 PAD* pad = static_cast<PAD*>( item );
366 FOOTPRINT* fp = static_cast<FOOTPRINT*>( pad->GetParentFootprint() );
367 msg = wxString::Format( _( "%s pad %s" ), fp->GetReference(), pad->GetNumber() );
368 }
369 else
370 {
371 msg = item->GetTypeDesc().Lower();
372 }
373
374 statusPopup.SetText( wxString::Format( popuptext, msg, ii, count ) );
375 };
376
377 std::vector<BOARD_ITEM*> sel_items; // All the items operated on by the move below
378 std::vector<BOARD_ITEM*> orig_items; // All the original items in the selection
379
380 for( EDA_ITEM* item : selection )
381 {
382 BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
383 FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item );
384
385 if( boardItem )
386 {
387 if( !is_hover )
388 orig_items.push_back( boardItem );
389
390 sel_items.push_back( boardItem );
391 }
392
393 if( footprint )
394 {
395 for( PAD* pad : footprint->Pads() )
396 sel_items.push_back( pad );
397
398 // Clear this flag here; it will be set by the netlist updater if the footprint is new
399 // so that it was skipped in the initial connectivity update in OnNetlistChanged
400 footprint->SetAttributes( footprint->GetAttributes() & ~FP_JUST_ADDED );
401 }
402 }
403
404 if( moveWithReference && !pickReferencePoint( _( "Select reference point for move..." ), "", "",
405 pickedReferencePoint ) )
406 {
407 if( is_hover )
409
410 editFrame->PopTool( aEvent );
411 return 0;
412 }
413
414 if( moveIndividually )
415 {
416 orig_items.clear();
417
419 orig_items.push_back( static_cast<BOARD_ITEM*>( item ) );
420
421 updateStatusPopup( orig_items[ itemIdx ], itemIdx + 1, orig_items.size() );
422 statusPopup.Popup();
423 statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
424 canvas()->SetStatusPopup( statusPopup.GetPanel() );
425
427 m_selectionTool->AddItemToSel( orig_items[ itemIdx ] );
428
429 sel_items.clear();
430 sel_items.push_back( orig_items[ itemIdx ] );
431 }
432
433 bool restore_state = false;
434 VECTOR2I originalPos;
435 VECTOR2I totalMovement;
436 VECTOR2D bboxMovement;
437 BOX2I originalBBox;
438 bool updateBBox = true;
440 TOOL_EVENT copy = aEvent;
441 TOOL_EVENT* evt = &copy;
442 VECTOR2I prevPos;
443
444 bool hv45Mode = false;
445 bool eatFirstMouseUp = true;
446 bool hasRedrawn3D = false;
447 bool allowRedraw3D = cfg->m_Display.m_Live3DRefresh;
448 bool showCourtyardConflicts = !m_isFootprintEditor && cfg->m_ShowCourtyardCollisions;
449
450 // Used to test courtyard overlaps
451 std::unique_ptr<DRC_INTERACTIVE_COURTYARD_CLEARANCE> drc_on_move = nullptr;
452
453 if( showCourtyardConflicts )
454 {
455 std::shared_ptr<DRC_ENGINE> drcEngine = m_toolMgr->GetTool<DRC_TOOL>()->GetDRCEngine();
456 drc_on_move.reset( new DRC_INTERACTIVE_COURTYARD_CLEARANCE( drcEngine ) );
457 drc_on_move->Init( board );
458 }
459
460 displayConstraintsMessage( hv45Mode );
461
462 // Prime the pump
464
465 // Main loop: keep receiving events
466 do
467 {
468 VECTOR2I movement;
470 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
471 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
472
473 bool isSkip = evt->IsAction( &PCB_ACTIONS::skip ) && moveIndividually;
474
475 if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
476 eatFirstMouseUp = false;
477
478 if( evt->IsAction( &PCB_ACTIONS::move ) || evt->IsMotion() || evt->IsDrag( BUT_LEFT )
482 {
483 if( m_dragging && evt->Category() == TC_MOUSE )
484 {
485 bool redraw3D = false;
486
487 VECTOR2I mousePos( controls->GetMousePosition() );
488
489 m_cursor = grid.BestSnapAnchor( mousePos, item_layers, sel_items );
490
492 {
494
495 // The arrow keys are by definition SINGLE AXIS. Do not allow the other
496 // axis to be snapped to the grid.
497 if( action == ACTIONS::CURSOR_LEFT || action == ACTIONS::CURSOR_RIGHT )
498 m_cursor.y = prevPos.y;
499 else if( action == ACTIONS::CURSOR_UP || action == ACTIONS::CURSOR_DOWN )
500 m_cursor.x = prevPos.x;
501 }
502
504 originalPos = m_cursor;
505
506 if( hv45Mode )
507 {
508 VECTOR2I moveVector = m_cursor - originalPos;
509 m_cursor = originalPos + GetVectorSnapped45( moveVector );
510 }
511
512 if( updateBBox )
513 {
514 originalBBox = BOX2I();
515 bboxMovement = VECTOR2D();
516
517 for( EDA_ITEM* item : sel_items )
518 {
519 BOX2I viewBBOX = item->ViewBBox();
520
521 if( originalBBox.GetWidth() == 0 && originalBBox.GetHeight() == 0 )
522 originalBBox = viewBBOX;
523 else
524 originalBBox.Merge( viewBBOX );
525 }
526
527 updateBBox = false;
528 }
529
530 // Constrain selection bounding box to coordinates limits
531 movement = getSafeMovement( m_cursor - prevPos, originalBBox, bboxMovement );
532
533 // Apply constrained movement
534 m_cursor = prevPos + movement;
535
538
539 prevPos = m_cursor;
540 totalMovement += movement;
541 bboxMovement += movement;
542
543 // Drag items to the current cursor position
544 for( EDA_ITEM* item : sel_items )
545 {
546 // Don't double move footprint pads, fields, etc.
547 //
548 // For PCB_GROUP_T, we make sure the selection includes only the top level
549 // group and not its descendants.
550 if( !item->GetParent() || !item->GetParent()->IsSelected() )
551 static_cast<BOARD_ITEM*>( item )->Move( movement );
552
553 if( !redraw3D && item->Type() == PCB_FOOTPRINT_T )
554 redraw3D = true;
555 }
556
557 if( redraw3D && allowRedraw3D )
558 {
559 editFrame->Update3DView( false, true );
560 hasRedrawn3D = true;
561 }
562
563 if( showCourtyardConflicts && drc_on_move->m_FpInMove.size() )
564 {
565 drc_on_move->Run();
566 drc_on_move->UpdateConflicts( m_toolMgr->GetView(), true );
567 }
568
570 }
571 else if( !m_dragging && !evt->IsAction( &ACTIONS::refreshPreview ) )
572 {
573 // Prepare to start dragging
574 editFrame->HideSolderMask();
575
576 m_dragging = true;
577
578 // When editing footprints, all items have the same parent
579 if( IsFootprintEditor() )
580 {
581 m_commit->Modify( selection.Front() );
582 }
583 else
584 {
585 // Save items, so changes can be undone
586 for( EDA_ITEM* item : selection )
587 {
588 // Don't double move footprint pads, fields, etc.
589 //
590 // For PCB_GROUP_T, the parent is the board.
591 if( item->GetParent() && item->GetParent()->IsSelected() )
592 continue;
593
594 m_commit->Modify( item );
595
596 // If moving a group, record position of all the descendants for undo
597 if( item->Type() == PCB_GROUP_T )
598 {
599 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
600 group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
601 {
602 m_commit->Modify( bItem );
603 });
604 }
605 }
606 }
607
608 editFrame->UndoRedoBlock( true );
610
612 {
613 // start moving with the reference point attached to the cursor
614 grid.SetAuxAxes( false );
615
616 if( hv45Mode )
617 {
618 VECTOR2I moveVector = m_cursor - originalPos;
619 m_cursor = originalPos + GetVectorSnapped45( moveVector );
620 }
621
622 movement = m_cursor - selection.GetReferencePoint();
623
624 // Drag items to the current cursor position
625 for( EDA_ITEM* item : selection )
626 {
627 // Don't double move footprint pads, fields, etc.
628 if( item->GetParent() && item->GetParent()->IsSelected() )
629 continue;
630
631 static_cast<BOARD_ITEM*>( item )->Move( movement );
632 }
633
635 }
636 else
637 {
638 for( BOARD_ITEM* item : sel_items )
639 {
640 if( showCourtyardConflicts && item->Type() == PCB_FOOTPRINT_T )
641 drc_on_move->m_FpInMove.push_back( static_cast<FOOTPRINT*>( item ) );
642 }
643
644 m_cursor = grid.BestDragOrigin( originalCursorPos, sel_items,
646
647 // Set the current cursor position to the first dragged item origin, so the
648 // movement vector could be computed later
649 if( moveWithReference )
650 {
651 selection.SetReferencePoint( pickedReferencePoint );
652 controls->ForceCursorPosition( true, pickedReferencePoint );
653 m_cursor = pickedReferencePoint;
654 }
655 else
656 {
657 // Check if user wants to warp the mouse to origin of moved object
658 if( !editFrame->GetMoveWarpsCursor() )
659 m_cursor = originalCursorPos; // No, so use original mouse pos instead
660
662 grid.SetAuxAxes( true, m_cursor );
663 }
664
665 originalPos = m_cursor;
666 }
667
668 // Update variables for bounding box collision calculations
669 updateBBox = true;
670
672
673 prevPos = m_cursor;
674 controls->SetAutoPan( true );
676 }
677
678 statusPopup.Move( wxGetMousePosition() + wxPoint( 20, 20 ) );
679
681 }
682 else if( evt->IsCancelInteractive() || evt->IsActivate() )
683 {
684 if( m_dragging && evt->IsCancelInteractive() )
685 evt->SetPassEvent( false );
686
687 restore_state = true; // Canceling the tool means that items have to be restored
688 break; // Finish
689 }
690 else if( evt->IsAction( &ACTIONS::undo ) )
691 {
692 restore_state = true; // Perform undo locally
693 break; // Finish
694 }
695 else if( evt->IsAction( &ACTIONS::doDelete ) || evt->IsAction( &ACTIONS::cut ) )
696 {
697 // Dispatch TOOL_ACTIONs
698 evt->SetPassEvent();
699 break; // finish -- there is no further processing for removed items
700 }
701 else if( evt->IsAction( &ACTIONS::duplicate ) )
702 {
703 evt->SetPassEvent();
704 break; // finish -- Duplicate tool will start a new Move with the dup'ed items
705 }
706 else if( evt->IsAction( &PCB_ACTIONS::rotateCw )
708 || evt->IsAction( &PCB_ACTIONS::flip )
710 || evt->IsAction( &PCB_ACTIONS::mirrorV ) )
711 {
712 updateBBox = true;
713 eatFirstMouseUp = false;
714 evt->SetPassEvent();
715 }
716 else if( evt->IsAction( &PCB_ACTIONS::moveExact ) )
717 {
718 // Reset positions so the Move Exactly is from the start.
719 for( EDA_ITEM* item : selection )
720 {
721 BOARD_ITEM* i = static_cast<BOARD_ITEM*>( item );
722 i->Move( -totalMovement );
723 }
724
725 break; // finish -- we moved exactly, so we are finished
726 }
727 else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) || isSkip )
728 {
729 // Eat mouse-up/-click events that leaked through from the lock dialog
730 if( eatFirstMouseUp && evt->Parameter<intptr_t>() != ACTIONS::CURSOR_CLICK )
731 {
732 eatFirstMouseUp = false;
733 continue;
734 }
735 else if( moveIndividually && m_dragging )
736 {
737 // Put skipped items back where they started
738 if( isSkip )
739 orig_items[itemIdx]->SetPosition( originalPos );
740
742
743 if( ++itemIdx < orig_items.size() )
744 {
745 BOARD_ITEM* nextItem = orig_items[itemIdx];
746
748
749 originalPos = nextItem->GetPosition();
750 m_selectionTool->AddItemToSel( nextItem );
751 selection.SetReferencePoint( originalPos );
752
753 sel_items.clear();
754 sel_items.push_back( nextItem );
755 updateStatusPopup( nextItem, itemIdx + 1, orig_items.size() );
756
757 // Pick up new item
758 m_commit->Modify( nextItem );
759 nextItem->SetPosition( controls->GetMousePosition( true ) );
760
761 continue;
762 }
763 }
764
765 break; // finish
766 }
767 else if( evt->IsDblClick( BUT_LEFT ) )
768 {
769 // The first click will move the new item, so put it back
770 if( moveIndividually )
771 orig_items[itemIdx]->SetPosition( originalPos );
772
773 break; // finish
774 }
775 else if( evt->IsAction( &PCB_ACTIONS::toggleHV45Mode ) )
776 {
777 hv45Mode = !hv45Mode;
778 displayConstraintsMessage( hv45Mode );
779 evt->SetPassEvent( false );
780 }
781 else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
782 {
783 wxBell();
784 }
785 else
786 {
787 evt->SetPassEvent();
788 }
789
790 } while( ( evt = Wait() ) ); // Assignment (instead of equality test) is intentional
791
792 // Clear temporary COURTYARD_CONFLICT flag and ensure the conflict shadow is cleared
793 if( showCourtyardConflicts )
794 drc_on_move->ClearConflicts( m_toolMgr->GetView() );
795
797 controls->ShowCursor( false );
798 controls->SetAutoPan( false );
799
800 m_dragging = false;
801 editFrame->UndoRedoBlock( false );
802
803 // Discard reference point when selection is "dropped" onto the board
805
806 // Unselect all items to clear selection flags and then re-select the originally selected
807 // items (after the potential Revert()).
809
810 // TODO: there's an encapsulation leak here: this commit often has more than just the move
811 // in it; for instance it might have a paste, append board, etc. as well.
812 if( restore_state )
813 {
814 m_commit->Revert();
816
817 // Mainly for point editor, but there might be other clients that need to adjust to
818 // reverted state.
820
821 // Property panel needs to know about the reselect
823
824 if( hasRedrawn3D )
825 editFrame->Update3DView( false, true );
826 }
827 else
828 {
829 m_commit->Push( aCommitMessage );
830 m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &orig_items );
831 }
832
833 m_toolMgr->GetTool<DRAWING_TOOL>()->UpdateStatusBar();
834 // Remove the dynamic ratsnest from the screen
836
837 editFrame->PopTool( aEvent );
839
840 return restore_state ? -1 : 0;
841}
BOX2< VECTOR2I > BOX2I
Definition: box2.h:847
@ CURSOR_RIGHT
Definition: actions.h:191
@ CURSOR_LEFT
Definition: actions.h:191
@ CURSOR_CLICK
Definition: actions.h:192
@ CURSOR_UP
Definition: actions.h:191
@ CURSOR_DOWN
Definition: actions.h:191
static TOOL_ACTION undo
Definition: actions.h:65
static TOOL_ACTION duplicate
Definition: actions.h:72
static TOOL_ACTION doDelete
Definition: actions.h:73
virtual void Move(const VECTOR2I &aMoveVector)
Move this object.
Definition: board_item.h:278
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:269
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetWidth() const
Definition: box2.h:187
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:588
Tool responsible for drawing graphical elements like lines, arcs, circles, etc.
Definition: drawing_tool.h:51
void DisplayConstraintsMsg(const wxString &msg)
void SetStatusPopup(wxWindow *aPopup)
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:249
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:250
wxString GetTypeDesc() const
Return a translated description of the type for this EDA_ITEM for display in user facing messages.
Definition: eda_item.cpp:301
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
bool IsSelected() const
Definition: eda_item.h:106
EDA_ITEM * GetParent() const
Definition: eda_item.h:99
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: eda_item.cpp:254
int Move(const TOOL_EVENT &aEvent)
Main loop in which events are handled.
VECTOR2I getSafeMovement(const VECTOR2I &aMovement, const BOX2I &aSourceBBox, const VECTOR2D &aBBoxOffset)
VECTOR2I m_cursor
Definition: edit_tool.h:212
void rebuildConnectivity()
Definition: edit_tool.cpp:2583
static const TOOL_EVENT SelectedItemsMoved
Used to inform tools that the selection should temporarily be non-editable.
Definition: actions.h:217
void SetAttributes(int aAttributes)
Definition: footprint.h:251
int GetAttributes() const
Definition: footprint.h:250
PADS & Pads()
Definition: footprint.h:170
const wxString & GetReference() const
Definition: footprint.h:519
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Move cursor to the requested position expressed in world coordinates.
const VC_SETTINGS & GetSettings() const
Apply VIEW_CONTROLS settings from an object.
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:532
bool m_ShowCourtyardCollisions
static TOOL_ACTION toggleHV45Mode
Definition: pcb_actions.h:466
static TOOL_ACTION mirrorH
Mirroring of selected items.
Definition: pcb_actions.h:129
static TOOL_ACTION hideLocalRatsnest
Definition: pcb_actions.h:507
static TOOL_ACTION moveWithReference
move with a reference point
Definition: pcb_actions.h:116
static TOOL_ACTION moveExact
Activation of the exact move tool.
Definition: pcb_actions.h:152
static TOOL_ACTION updateLocalRatsnest
Definition: pcb_actions.h:508
static TOOL_ACTION moveIndividually
move items one-by-one
Definition: pcb_actions.h:113
static TOOL_ACTION skip
Definition: pcb_actions.h:139
static TOOL_ACTION move
move or drag an item
Definition: pcb_actions.h:110
static TOOL_ACTION mirrorV
Definition: pcb_actions.h:130
static TOOL_ACTION selectItems
Select a list of items (specified as the event parameter)
Definition: pcb_actions.h:66
static TOOL_ACTION rotateCw
Rotation of selected objects.
Definition: pcb_actions.h:122
static TOOL_ACTION rotateCcw
Definition: pcb_actions.h:123
Common, abstract interface for edit frames.
void UndoRedoBlock(bool aBlock=true)
Enable/disable undo and redo operations.
virtual MAGNETIC_SETTINGS * GetMagneticItemsSettings()
BOARD * GetBoard() const
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
void FilterCollectorForFreePads(GENERAL_COLLECTOR &aCollector) const
Check the "allow free pads" setting and if disabled, replace any pads in the collector with their par...
SELECTION_FILTER_OPTIONS & GetFilter()
Set up handlers for various events.
void RebuildSelection()
Rebuild the selection from the EDA_ITEMs' selection flags.
const LSET GetSelectionLayers()
FOOTPRINT * footprint() const
int AddItemToSel(const TOOL_EVENT &aEvent)
const std::vector< EDA_ITEM * > GetItemsSortedBySelectionOrder() const
Definition: selection.cpp:201
VECTOR2I GetReferencePoint() const
Definition: selection.h:252
EDA_ITEM * Front() const
Definition: selection.h:208
void ClearReferencePoint()
Definition: selection.h:265
bool HasReferencePoint() const
Definition: selection.h:247
Extension of STATUS_POPUP for displaying a single line text.
Definition: status_popup.h:83
bool GetMoveWarpsCursor() const
Indicate that a move operation should warp the mouse pointer to the origin of the move object.
Definition: tools_holder.h:153
bool DisableGridSnapping() const
Definition: tool_event.h:344
bool IsCancelInteractive() const
Indicate the event should restart/end an ongoing interactive tool's event loop (eg esc key,...
Definition: tool_event.cpp:205
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:442
bool IsActivate() const
Definition: tool_event.h:318
bool IsClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.cpp:193
bool IsDrag(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:288
int Modifier(int aMask=MD_MODIFIER_MASK) const
Definition: tool_event.h:339
bool IsDblClick(int aButtonMask=BUT_ANY) const
Definition: tool_event.cpp:199
void SetPassEvent(bool aPass=true)
Returns if it this event has a valid position (true for mouse events and context-menu or hotkey-based...
Definition: tool_event.h:239
bool IsMouseUp(int aButtonMask=BUT_ANY) const
Definition: tool_event.h:298
bool IsMotion() const
Definition: tool_event.h:303
void PostEvent(const TOOL_EVENT &aEvent)
Put an event to the event queue to be processed at the end of event processing cycle.
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:285
static bool IsZoneFillAction(const TOOL_EVENT *aEvent)
VECTOR2< T > GetVectorSnapped45(const VECTOR2< T > &aVec, bool only45=false)
Snap a vector onto the nearest 0, 45 or 90 degree line.
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
bool m_lastKeyboardCursorPositionValid
ACTIONS::CURSOR_UP, ACTIONS::CURSOR_DOWN, etc.
long m_lastKeyboardCursorCommand
Position of the above event.
@ TC_MOUSE
Definition: tool_event.h:50
@ MD_SHIFT
Definition: tool_event.h:138
VECTOR2< double > VECTOR2D
Definition: vector2d.h:589
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590

References _, TOOL_INTERACTIVE::Activate(), SELECTION_TOOL::AddItemToSel(), ARROW, PCB_TOOL_BASE::board(), BUT_LEFT, PCB_TOOL_BASE::canvas(), TOOL_EVENT::Category(), SELECTION::ClearReferencePoint(), PCB_SELECTION_TOOL::ClearSelection(), PCB_TOOL_BASE::controls(), copy, ACTIONS::CURSOR_CLICK, ACTIONS::CURSOR_DOWN, ACTIONS::CURSOR_LEFT, ACTIONS::CURSOR_RIGHT, ACTIONS::CURSOR_UP, ACTIONS::cut, TOOL_EVENT::DisableGridSnapping(), EDA_DRAW_FRAME::DisplayConstraintsMsg(), ACTIONS::doDelete, ACTIONS::duplicate, SELECTION::Empty(), PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), PCB_ACTIONS::flip, PCB_TOOL_BASE::footprint(), KIGFX::VIEW_CONTROLS::ForceCursorPosition(), Format(), PCB_TOOL_BASE::frame(), SELECTION::Front(), FOOTPRINT::GetAttributes(), PCB_BASE_FRAME::GetBoard(), PCB_BASE_FRAME::GetCanvas(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_SELECTION_TOOL::GetFilter(), BOX2< Vec >::GetHeight(), SELECTION::GetItemsSortedBySelectionOrder(), PCB_BASE_FRAME::GetMagneticItemsSettings(), KIGFX::VIEW_CONTROLS::GetMousePosition(), TOOLS_HOLDER::GetMoveWarpsCursor(), STATUS_POPUP::GetPanel(), EDA_ITEM::GetParent(), PCB_BASE_FRAME::GetPcbNewSettings(), EDA_ITEM::GetPosition(), FOOTPRINT::GetReference(), SELECTION::GetReferencePoint(), getSafeMovement(), PCB_SELECTION::GetSelectionLayers(), KIGFX::VIEW_CONTROLS::GetSettings(), TOOL_MANAGER::GetTool(), EDA_ITEM::GetTypeDesc(), GetVectorSnapped45(), TOOL_BASE::getView(), TOOL_MANAGER::GetView(), TOOL_BASE::getViewControls(), BOX2< Vec >::GetWidth(), grid, group, SELECTION::HasReferencePoint(), PCB_ACTIONS::hideLocalRatsnest, PCB_BASE_FRAME::HideSolderMask(), TOOL_EVENT::IsAction(), TOOL_EVENT::IsActivate(), TOOL_EVENT::IsCancelInteractive(), TOOL_EVENT::IsClick(), TOOL_EVENT::IsDblClick(), TOOL_EVENT::IsDrag(), PCB_TOOL_BASE::IsFootprintEditor(), SELECTION::IsHover(), TOOL_EVENT::IsMotion(), TOOL_EVENT::IsMouseUp(), EDA_ITEM::IsSelected(), ZONE_FILLER_TOOL::IsZoneFillAction(), PCBNEW_SETTINGS::m_AllowFreePads, m_commit, m_cursor, PCBNEW_SETTINGS::m_Display, m_dragging, PCB_TOOL_BASE::m_isFootprintEditor, KIGFX::VC_SETTINGS::m_lastKeyboardCursorCommand, KIGFX::VC_SETTINGS::m_lastKeyboardCursorPositionValid, PCBNEW_SETTINGS::DISPLAY_OPTIONS::m_Live3DRefresh, m_selectionTool, PCBNEW_SETTINGS::m_ShowCourtyardCollisions, TOOL_BASE::m_toolMgr, MD_SHIFT, BOX2< Vec >::Merge(), PCB_ACTIONS::mirrorH, PCB_ACTIONS::mirrorV, TOOL_EVENT::Modifier(), Move(), BOARD_ITEM::Move(), STATUS_POPUP::Move(), PCB_ACTIONS::move, PCB_ACTIONS::moveExact, PCB_ACTIONS::moveIndividually, PCB_ACTIONS::moveWithReference, MOVING, pad, FOOTPRINT::Pads(), TOOL_EVENT::Parameter(), PCB_FOOTPRINT_T, PCB_GROUP_T, PCB_PAD_T, pickReferencePoint(), TOOLS_HOLDER::PopTool(), STATUS_POPUP::Popup(), TOOL_MANAGER::PostEvent(), TOOLS_HOLDER::PushTool(), rebuildConnectivity(), PCB_SELECTION_TOOL::RebuildSelection(), ACTIONS::refreshPreview, PCB_SELECTION_TOOL::RequestSelection(), PCB_ACTIONS::rotateCcw, PCB_ACTIONS::rotateCw, TOOL_MANAGER::RunAction(), EVENTS::SelectedItemsModified, EVENTS::SelectedItemsMoved, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItems, FOOTPRINT::SetAttributes(), KIGFX::VIEW_CONTROLS::SetAutoPan(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), KIGFX::VIEW_CONTROLS::SetCursorPosition(), TOOL_EVENT::SetPassEvent(), EDA_ITEM::SetPosition(), SELECTION::SetReferencePoint(), EDA_DRAW_PANEL_GAL::SetStatusPopup(), STATUS_TEXT_POPUP::SetText(), KIGFX::VIEW_CONTROLS::ShowCursor(), PCB_ACTIONS::skip, TC_MOUSE, PCB_ACTIONS::toggleHV45Mode, EDA_ITEM::Type(), ACTIONS::undo, PCB_BASE_EDIT_FRAME::UndoRedoBlock(), PCB_BASE_FRAME::Update3DView(), PCB_ACTIONS::updateLocalRatsnest, EDA_ITEM::ViewBBox(), TOOL_INTERACTIVE::Wait(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Move(), and PackAndMoveFootprints().

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

336{
337 if( !m_toolMgr->GetTool<ROUTER_TOOL>() )
338 return false; // don't drag when no router tool (i.e. fp editor)
339
341 return false; // don't drag when router is already active
342
343 int mode = PNS::DM_ANY;
344
345 if( aEvent.IsAction( &PCB_ACTIONS::dragFreeAngle ) )
346 mode |= PNS::DM_FREE_ANGLE;
347
349 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
350 {
351 sTool->FilterCollectorForFreePads( aCollector );
352 sTool->FilterCollectorForHierarchy( aCollector, true );
353
354 if( aCollector.GetCount() > 1 )
355 sTool->GuessSelectionCandidates( aCollector, aPt );
356
357 /*
358 * If we have a knee between two segments, or a via attached to two segments,
359 * then drop the selection to a single item.
360 */
361
362 std::vector<PCB_TRACK*> tracks;
363 std::vector<PCB_TRACK*> vias;
364
365 for( EDA_ITEM* item : aCollector )
366 {
367 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
368 {
369 if( track->Type() == PCB_VIA_T )
370 vias.push_back( track );
371 else
372 tracks.push_back( track );
373 }
374 }
375
376 auto connected = []( PCB_TRACK* track, const VECTOR2I& pt )
377 {
378 return track->GetStart() == pt || track->GetEnd() == pt;
379 };
380
381 if( tracks.size() == 2 && vias.size() == 0 )
382 {
383 if( connected( tracks[0], tracks[1]->GetStart() )
384 || connected( tracks[0], tracks[1]->GetEnd() ) )
385 {
386 aCollector.Remove( tracks[1] );
387 }
388 }
389 else if( tracks.size() == 2 && vias.size() == 1 )
390 {
391 if( connected( tracks[0], vias[0]->GetPosition() )
392 && connected( tracks[1], vias[0]->GetPosition() ) )
393 {
394 aCollector.Remove( tracks[0] );
395 aCollector.Remove( tracks[1] );
396 }
397 }
398 },
399 true /* prompt user regarding locked items */ );
400
401 if( selection.Empty() )
402 return 0;
403
404 if( selection.Size() == 1 && selection.Front()->Type() == PCB_ARC_T )
405 {
406 // TODO: This really should be done in PNS to ensure DRC is maintained, but for now
407 // it allows interactive editing of an arc track
408 return DragArcTrack( aEvent );
409 }
410 else
411 {
412 invokeInlineRouter( mode );
413 }
414
415 return 0;
416}
void Remove(int aIndex)
Remove the item at aIndex (first position is 0).
Definition: collector.h:109
int DragArcTrack(const TOOL_EVENT &aTrack)
Drag-resize an arc (and change end points of connected straight segments).
Definition: edit_tool.cpp:419
bool invokeInlineRouter(int aDragMode)
Definition: edit_tool.cpp:297
static TOOL_ACTION dragFreeAngle
Definition: pcb_actions.h:167
void GuessSelectionCandidates(GENERAL_COLLECTOR &aCollector, const VECTOR2I &aWhere) const
Try to guess best selection candidates in case multiple items are clicked, by doing some brain-dead h...
const VECTOR2I & GetStart() const
Definition: pcb_track.h:114
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:111
int Size() const
Returns the number of selected parts.
Definition: selection.h:115
bool IsToolActive() const
Definition: tool_base.cpp:31
@ DM_ANY
Definition: pns_router.h:77
@ DM_FREE_ANGLE
Definition: pns_router.h:75

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

Referenced by setTransitions().

◆ DragArcTrack()

int EDIT_TOOL::DragArcTrack ( const TOOL_EVENT aTrack)

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

Definition at line 419 of file edit_tool.cpp.

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

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

◆ Duplicate()

int EDIT_TOOL::Duplicate ( const TOOL_EVENT aEvent)

Duplicate the current selection and starts a move action.

Definition at line 2190 of file edit_tool.cpp.

2191{
2192 if( isRouterActive() )
2193 {
2194 wxBell();
2195 return 0;
2196 }
2197
2198 bool increment = aEvent.IsAction( &PCB_ACTIONS::duplicateIncrement );
2199
2200 // Be sure that there is at least one item that we can modify
2202 []( const VECTOR2I&, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2203 {
2204 sTool->FilterCollectorForMarkers( aCollector );
2205 sTool->FilterCollectorForHierarchy( aCollector, true );
2206 } );
2207
2208 if( selection.Empty() )
2209 return 0;
2210
2211 // we have a selection to work on now, so start the tool process
2212 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
2213
2214 // If the selection was given a hover, we do not keep the selection after completion
2215 bool is_hover = selection.IsHover();
2216
2217 std::vector<BOARD_ITEM*> new_items;
2218 new_items.reserve( selection.Size() );
2219
2220 // Each selected item is duplicated and pushed to new_items list
2221 // Old selection is cleared, and new items are then selected.
2222 for( EDA_ITEM* item : selection )
2223 {
2224 BOARD_ITEM* dupe_item = nullptr;
2225 BOARD_ITEM* orig_item = static_cast<BOARD_ITEM*>( item );
2226
2228 {
2229 FOOTPRINT* parentFootprint = editFrame->GetBoard()->GetFirstFootprint();
2230 dupe_item = parentFootprint->DuplicateItem( orig_item );
2231
2232 if( increment && dupe_item->Type() == PCB_PAD_T
2233 && static_cast<PAD*>( dupe_item )->CanHaveNumber() )
2234 {
2235 PAD_TOOL* padTool = m_toolMgr->GetTool<PAD_TOOL>();
2236 wxString padNumber = padTool->GetLastPadNumber();
2237 padNumber = parentFootprint->GetNextPadNumber( padNumber );
2238 padTool->SetLastPadNumber( padNumber );
2239 static_cast<PAD*>( dupe_item )->SetNumber( padNumber );
2240 }
2241 }
2242 else if( orig_item->GetParent() && orig_item->GetParent()->Type() == PCB_FOOTPRINT_T )
2243 {
2244 FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( orig_item->GetParent() );
2245
2246 m_commit->Modify( parentFootprint );
2247 dupe_item = parentFootprint->DuplicateItem( orig_item, true /* add to parent */ );
2248 }
2249 else
2250 {
2251 switch( orig_item->Type() )
2252 {
2253 case PCB_FOOTPRINT_T:
2254 case PCB_TEXT_T:
2255 case PCB_TEXTBOX_T:
2256 case PCB_BITMAP_T:
2257 case PCB_SHAPE_T:
2258 case PCB_TRACE_T:
2259 case PCB_ARC_T:
2260 case PCB_VIA_T:
2261 case PCB_ZONE_T:
2262 case PCB_TARGET_T:
2263 case PCB_DIM_ALIGNED_T:
2264 case PCB_DIM_CENTER_T:
2265 case PCB_DIM_RADIAL_T:
2267 case PCB_DIM_LEADER_T:
2268 dupe_item = orig_item->Duplicate();
2269 break;
2270
2271 case PCB_GROUP_T:
2272 dupe_item = static_cast<PCB_GROUP*>( orig_item )->DeepDuplicate();
2273 break;
2274
2275 default:
2276 wxASSERT_MSG( false, wxString::Format( wxT( "Unhandled item type %d" ),
2277 orig_item->Type() ) );
2278 break;
2279 }
2280 }
2281
2282 if( dupe_item )
2283 {
2284 if( dupe_item->Type() == PCB_GROUP_T )
2285 {
2286 static_cast<PCB_GROUP*>( dupe_item )->RunOnDescendants(
2287 [&]( BOARD_ITEM* bItem )
2288 {
2289 m_commit->Add( bItem );
2290 });
2291 }
2292
2293 // Clear the selection flag here, otherwise the PCB_SELECTION_TOOL
2294 // will not properly select it later on
2295 dupe_item->ClearSelected();
2296
2297 new_items.push_back( dupe_item );
2298 m_commit->Add( dupe_item );
2299 }
2300 }
2301
2302 // Clear the old selection first
2304
2305 // Select the new items
2306 m_toolMgr->RunAction( PCB_ACTIONS::selectItems, true, &new_items );
2307
2308 // record the new items as added
2309 if( !selection.Empty() )
2310 {
2311 editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
2312 (int) new_items.size() ) );
2313
2314 // TODO(ISM): This line can't be used to activate the tool until we allow multiple
2315 // activations.
2316 // m_toolMgr->RunAction( PCB_ACTIONS::move, true );
2317 // Instead we have to create the event and call the tool's function
2318 // directly
2319
2320 // If items were duplicated, pick them up
2321 // this works well for "dropping" copies around and pushes the commit
2323 Move( evt );
2324
2325 // Deslect the duplicated item if we originally started as a hover selection
2326 if( is_hover )
2328 }
2329
2330 return 0;
2331}
virtual BOARD_ITEM * Duplicate() const
Create a copy of this BOARD_ITEM.
Definition: board_item.cpp:184
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
Definition: board.h:403
void DisplayToolMsg(const wxString &msg) override
void ClearSelected()
Definition: eda_item.h:118
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:1887
wxString GetNextPadNumber(const wxString &aLastPadName) const
Return the next available pad number in the footprint.
Definition: footprint.cpp:1999
Tool relating to pads and pad settings.
Definition: pad_tool.h:37
void SetLastPadNumber(const wxString &aPadNumber)
Definition: pad_tool.h:66
wxString GetLastPadNumber() const
Definition: pad_tool.h:65
static TOOL_ACTION duplicateIncrement
Activation of the duplication tool with incrementing (e.g. pad number)
Definition: pcb_actions.h:155
TOOL_EVENT MakeEvent() const
Return the event associated with the action (i.e.
Definition: tool_action.cpp:72
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:110
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:107
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:108
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:91
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:90
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:111
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:106
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:109

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

Referenced by setTransitions().

◆ FilletLines()

int EDIT_TOOL::FilletLines ( const TOOL_EVENT aEvent)

Fillet (i.e.

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

Definition at line 1058 of file edit_tool.cpp.

1059{
1060 // Store last used fillet radius to allow pressing "enter" if repeat fillet is required
1061 static long long filletRadiusIU = 0;
1062
1064 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1065 {
1066
1067 std::vector<VECTOR2I> pts;
1068
1069 // Iterate from the back so we don't have to worry about removals.
1070 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
1071 {
1072 BOARD_ITEM* item = aCollector[i];
1073
1074 // We've converted the polygon and rectangle to segments, so drop everything
1075 // that isn't a segment at this point
1076 if( !item->IsType( { PCB_SHAPE_LOCATE_SEGMENT_T,
1077 PCB_SHAPE_LOCATE_POLY_T,
1078 PCB_SHAPE_LOCATE_RECT_T } ) )
1079 {
1080 aCollector.Remove( item );
1081 }
1082 }
1083 },
1084 true /* prompt user regarding locked items */ );
1085
1086 std::set<PCB_SHAPE*> lines_to_add;
1087 std::vector<PCB_SHAPE*> items_to_remove;
1088
1089 for( EDA_ITEM* item : selection )
1090 {
1091 std::vector<VECTOR2I> pts;
1092 PCB_SHAPE *graphic = static_cast<PCB_SHAPE*>( item );
1093 PCB_LAYER_ID layer = graphic->GetLayer();
1094 int width = graphic->GetWidth();
1095
1096 if( graphic->GetShape() == SHAPE_T::RECT )
1097 {
1098 items_to_remove.push_back( graphic );
1099 VECTOR2I start( graphic->GetStart() );
1100 VECTOR2I end( graphic->GetEnd() );
1101 pts.emplace_back( start );
1102 pts.emplace_back( VECTOR2I( end.x, start.y ) );
1103 pts.emplace_back( end );
1104 pts.emplace_back( VECTOR2I( start.x, end.y ) );
1105 }
1106
1107 if( graphic->GetShape() == SHAPE_T::POLY )
1108 {
1109 items_to_remove.push_back( graphic );
1110
1111 for( int jj = 0; jj < graphic->GetPolyShape().VertexCount(); ++jj )
1112 pts.emplace_back( graphic->GetPolyShape().CVertex( jj ) );
1113 }
1114
1115 for( size_t jj = 1; jj < pts.size(); ++jj )
1116 {
1117 PCB_SHAPE *line;
1118
1120 line = new FP_SHAPE( static_cast<FOOTPRINT*>( frame()->GetModel() ), SHAPE_T::SEGMENT );
1121 else
1122 line = new PCB_SHAPE( frame()->GetModel(), SHAPE_T::SEGMENT );
1123
1124 line->SetStart( pts[jj - 1] );
1125 line->SetEnd( pts[jj] );
1126 line->SetWidth( width );
1127 line->SetLayer( layer );
1128 lines_to_add.insert( line );
1129 }
1130
1131 if( pts.size() > 1 )
1132 {
1133 PCB_SHAPE *line;
1134
1136 line = new FP_SHAPE( static_cast<FOOTPRINT*>( frame()->GetModel() ), SHAPE_T::SEGMENT );
1137 else
1138 line = new PCB_SHAPE( frame()->GetModel(), SHAPE_T::SEGMENT );
1139
1140 line->SetStart( pts.back() );
1141 line->SetEnd( pts.front() );
1142 line->SetWidth( width );
1143 line->SetLayer( layer );
1144 lines_to_add.insert( line );
1145 }
1146 }
1147
1148 for( PCB_SHAPE* item : lines_to_add )
1149 selection.Add( item );
1150
1151 for( PCB_SHAPE* item : items_to_remove )
1152 selection.Remove( item );
1153
1155 {
1156 frame()->ShowInfoBarMsg( _( "A shape with least two lines must be selected." ) );
1157 return 0;
1158 }
1159
1160 WX_UNIT_ENTRY_DIALOG dia( frame(), _( "Enter fillet radius:" ), _( "Fillet Lines" ),
1161 filletRadiusIU );
1162
1163 if( dia.ShowModal() == wxID_CANCEL )
1164 return 0;
1165
1166 filletRadiusIU = dia.GetValue();
1167
1168 if( filletRadiusIU == 0 )
1169 {
1170 frame()->ShowInfoBarMsg( _( "A radius of zero was entered.\n"
1171 "The fillet operation was not performed." ) );
1172 return 0;
1173 }
1174
1175 bool operationPerformedOnAtLeastOne = false;
1176 bool didOneAttemptFail = false;
1177 std::vector<BOARD_ITEM*> itemsToAddToSelection;
1178
1179 // Only modify one parent in FP editor
1181 m_commit->Modify( selection.Front() );
1182
1184 {
1185 PCB_SHAPE* line_a = static_cast<PCB_SHAPE*>( a );
1186 PCB_SHAPE* line_b = static_cast<PCB_SHAPE*>( b );
1187
1188 if( line_a->GetLength() == 0.0 || line_b->GetLength() == 0 )
1189 return;
1190
1191 SEG seg_a( line_a->GetStart(), line_a->GetEnd() );
1192 SEG seg_b( line_b->GetStart(), line_b->GetEnd() );
1193 VECTOR2I* a_pt;
1194 VECTOR2I* b_pt;
1195
1196 if (seg_a.A == seg_b.A)
1197 {
1198 a_pt = &seg_a.A;
1199 b_pt = &seg_b.A;
1200 }
1201 else if (seg_a.A == seg_b.B)
1202 {
1203 a_pt = &seg_a.A;
1204 b_pt = &seg_b.B;
1205 }
1206 else if (seg_a.B == seg_b.A)
1207 {
1208 a_pt = &seg_a.B;
1209 b_pt = &seg_b.A;
1210 }
1211 else if (seg_a.B == seg_b.B)
1212 {
1213 a_pt = &seg_a.B;
1214 b_pt = &seg_b.B;
1215 }
1216 else
1217 return;
1218
1219
1220 SHAPE_ARC sArc( seg_a, seg_b, filletRadiusIU );
1221 VECTOR2I t1newPoint, t2newPoint;
1222
1223 auto setIfPointOnSeg =
1224 []( VECTOR2I& aPointToSet, SEG aSegment, VECTOR2I aVecToTest )
1225 {
1226 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
1227
1228 // Find out if we are on the segment (minimum precision)
1230 {
1231 aPointToSet.x = aVecToTest.x;
1232 aPointToSet.y = aVecToTest.y;
1233 return true;
1234 }
1235
1236 return false;
1237 };
1238
1239 //Do not draw a fillet if the end points of the arc are not within the track segments
1240 if( !setIfPointOnSeg( t1newPoint, seg_a, sArc.GetP0() )
1241 && !setIfPointOnSeg( t2newPoint, seg_b, sArc.GetP0() ) )
1242 {
1243 didOneAttemptFail = true;
1244 return;
1245 }
1246
1247 if( !setIfPointOnSeg( t1newPoint, seg_a, sArc.GetP1() )
1248 && !setIfPointOnSeg( t2newPoint, seg_b, sArc.GetP1() ) )
1249 {
1250 didOneAttemptFail = true;
1251 return;
1252 }
1253
1254 PCB_SHAPE* tArc;
1255
1257 tArc = new FP_SHAPE( static_cast<FOOTPRINT*>( frame()->GetModel() ), SHAPE_T::ARC );
1258 else
1259 tArc = new PCB_SHAPE( frame()->GetBoard(), SHAPE_T::ARC );
1260
1261 tArc->SetArcGeometry( sArc.GetP0(), sArc.GetArcMid(), sArc.GetP1() );
1262 tArc->SetWidth( line_a->GetWidth() );
1263 tArc->SetLayer( line_a->GetLayer() );
1264 tArc->SetLocked( line_a->IsLocked() );
1265
1266 if( lines_to_add.count( line_a ) )
1267 {
1268 lines_to_add.erase( line_a );
1269 itemsToAddToSelection.push_back( line_a );
1270 }
1271 else if( !m_isFootprintEditor )
1272 {
1273 m_commit->Modify( line_a );
1274 }
1275
1276 if( lines_to_add.count( line_b ) )
1277 {
1278 lines_to_add.erase( line_b );
1279 itemsToAddToSelection.push_back( line_b );
1280 }
1281 else if( !m_isFootprintEditor )
1282 {
1283 m_commit->Modify( line_b );
1284 }
1285
1286 itemsToAddToSelection.push_back( tArc );
1287 *a_pt = t1newPoint;
1288 *b_pt = t2newPoint;
1289 line_a->SetStart( seg_a.A );
1290 line_a->SetEnd( seg_a.B );
1291 line_b->SetStart( seg_b.A );
1292 line_b->SetEnd( seg_b.B );
1293
1295 {
1296 static_cast<FP_SHAPE*>( line_a )->SetLocalCoord();
1297 static_cast<FP_SHAPE*>( line_b )->SetLocalCoord();
1298 static_cast<FP_SHAPE*>( tArc )->SetLocalCoord();
1299 }
1300
1301 operationPerformedOnAtLeastOne = true;
1302
1303 } );
1304
1305 for( auto item : items_to_remove )
1306 {
1307 m_commit->Remove( item );
1308 m_selectionTool->RemoveItemFromSel( item, true );
1309 }
1310
1311 //select the newly created arcs
1312 for( BOARD_ITEM* item : itemsToAddToSelection )
1313 {
1314 m_commit->Add( item );
1315 m_selectionTool->AddItemToSel( item, true );
1316 }
1317
1318 if( !items_to_remove.empty() )
1320
1321 if( !itemsToAddToSelection.empty() )
1323
1324 // Notify other tools of the changes
1326
1327 m_commit->Push( _( "Fillet Lines" ) );
1328
1329 if( !operationPerformedOnAtLeastOne )
1330 frame()->ShowInfoBarMsg( _( "Unable to fillet the selected lines." ) );
1331 else if( didOneAttemptFail )
1332 frame()->ShowInfoBarMsg( _( "Some of the lines could not be filleted." ) );
1333
1334 return 0;
1335}
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...
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:247
SHAPE_T GetShape() const
Definition: eda_shape.h:113
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:145
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:124
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:120
int GetWidth() const
Definition: eda_shape.h:109
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:149
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
Definition: eda_shape.cpp:555
void SetWidth(int aWidth)
Definition: eda_shape.h:108
static const TOOL_EVENT SelectedEvent
Definition: actions.h:207
static const TOOL_EVENT UnselectedEvent
Definition: actions.h:208
int RemoveItemFromSel(const TOOL_EVENT &aEvent)
ITER end()
Definition: selection.h:74
ITER begin()
Definition: selection.h:73
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.cpp:60
size_t CountType(KICAD_T aType) const
Definition: selection.cpp:156
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the aGlobalIndex-th vertex in the poly set.
static const int MIN_PRECISION_IU
This is the minimum precision for all the points in a shape.
Definition: shape.h:129
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:265
An extension of WX_TEXT_ENTRY_DIALOG that uses UNIT_BINDER to request a dimension (e....
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
SGLIB_API S3DMODEL * GetModel(SCENEGRAPH *aNode)
Function GetModel creates an S3DMODEL representation of aNode (raw data, no transforms)
Definition: ifsg_api.cpp:338
void for_all_pairs(_InputIterator __first, _InputIterator __last, _Function __f)
Apply a function to every possible pair of elements of a sequence.
Definition: kicad_algo.h:83
BOARD * GetBoard()
@ PCB_SHAPE_LOCATE_SEGMENT_T
Definition: typeinfo.h:131

References COLLECTOR::GetCount(), m_selectionTool, COLLECTOR::Remove(), PCB_SELECTION_TOOL::RequestSelection(), and PCB_TOOL_BASE::selection().

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

855{
856 // Store last used fillet radius to allow pressing "enter" if repeat fillet is required
857 static long long filletRadiusIU = 0;
858
860 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
861 {
862 // Iterate from the back so we don't have to worry about removals.
863 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
864 {
865 BOARD_ITEM* item = aCollector[i];
866
867 if( !dynamic_cast<PCB_TRACK*>( item ) )
868 aCollector.Remove( item );
869 }
870 },
871 true /* prompt user regarding locked items */ );
872
873 if( selection.Size() < 2 )
874 {
875 frame()->ShowInfoBarMsg( _( "At least two straight track segments must be selected." ) );
876 return 0;
877 }
878
879 WX_UNIT_ENTRY_DIALOG dia( frame(), _( "Enter fillet radius:" ), _( "Fillet Tracks" ),
880 filletRadiusIU );
881
882 if( dia.ShowModal() == wxID_CANCEL )
883 return 0;
884
885 filletRadiusIU = dia.GetValue();
886
887 if( filletRadiusIU == 0 )
888 {
889 frame()->ShowInfoBarMsg( _( "A radius of zero was entered.\n"
890 "The fillet operation was not performed." ) );
891 return 0;
892 }
893
894 struct FILLET_OP
895 {
896 PCB_TRACK* t1;
897 PCB_TRACK* t2;
898 // Start point of track is modified after PCB_ARC is added, otherwise the end point:
899 bool t1Start = true;
900 bool t2Start = true;
901 };
902
903 std::vector<FILLET_OP> filletOperations;
904 bool operationPerformedOnAtLeastOne = false;
905 bool didOneAttemptFail = false;
906 std::set<PCB_TRACK*> processedTracks;
907
908 for( EDA_ITEM* item : selection )
909 {
910 PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item );
911
912 if( !track || track->Type() != PCB_TRACE_T || track->GetLength() == 0 )
913 {
914 continue;
915 }
916
917 auto processFilletOp =
918 [&]( bool aStartPoint )
919 {
920 std::shared_ptr<CONNECTIVITY_DATA> c = board()->GetConnectivity();
921 VECTOR2I anchor = aStartPoint ? track->GetStart()
922 : track->GetEnd();
923 std::vector<BOARD_CONNECTED_ITEM*> itemsOnAnchor;
924
925 itemsOnAnchor = c->GetConnectedItemsAtAnchor( track, anchor,
928
929 if( itemsOnAnchor.size() > 0
930 && selection.Contains( itemsOnAnchor.at( 0 ) )
931 && itemsOnAnchor.at( 0 )->Type() == PCB_TRACE_T )
932 {
933 PCB_TRACK* trackOther = dyn_cast<PCB_TRACK*>( itemsOnAnchor.at( 0 ) );
934
935 // Make sure we don't fillet the same pair of tracks twice
936 if( processedTracks.find( trackOther ) == processedTracks.end() )
937 {
938 if( itemsOnAnchor.size() == 1 )
939 {
940 FILLET_OP filletOp;
941 filletOp.t1 = track;
942 filletOp.t2 = trackOther;
943 filletOp.t1Start = aStartPoint;
944 filletOp.t2Start = track->IsPointOnEnds( filletOp.t2->GetStart() );
945 filletOperations.push_back( filletOp );
946 }
947 else
948 {
949 // User requested to fillet these two tracks but not possible as
950 // there are other elements connected at that point
951 didOneAttemptFail = true;
952 }
953 }
954 }
955 };
956
957 processFilletOp( true ); // on the start point of track
958 processFilletOp( false ); // on the end point of track
959
960 processedTracks.insert( track );
961 }
962
963 std::vector<BOARD_ITEM*> itemsToAddToSelection;
964
965 for( FILLET_OP filletOp : filletOperations )
966 {
967 PCB_TRACK* track1 = filletOp.t1;
968 PCB_TRACK* track2 = filletOp.t2;
969
970 bool trackOnStart = track1->IsPointOnEnds( track2->GetStart() );
971 bool trackOnEnd = track1->IsPointOnEnds( track2->GetEnd() );
972
973 if( trackOnStart && trackOnEnd )
974 continue; // Ignore duplicate tracks
975
976 if( ( trackOnStart || trackOnEnd ) && track1->GetLayer() == track2->GetLayer() )
977 {
978 SEG t1Seg( track1->GetStart(), track1->GetEnd() );
979 SEG t2Seg( track2->GetStart(), track2->GetEnd() );
980
981 if( t1Seg.ApproxCollinear( t2Seg ) )
982 continue;
983
984 SHAPE_ARC sArc( t1Seg, t2Seg, filletRadiusIU );
985 VECTOR2I t1newPoint, t2newPoint;
986
987 auto setIfPointOnSeg =
988 []( VECTOR2I& aPointToSet, SEG aSegment, VECTOR2I aVecToTest )
989 {
990 VECTOR2I segToVec = aSegment.NearestPoint( aVecToTest ) - aVecToTest;
991
992 // Find out if we are on the segment (minimum precision)
994 {
995 aPointToSet.x = aVecToTest.x;
996 aPointToSet.y = aVecToTest.y;
997 return true;
998 }
999
1000 return false;
1001 };
1002
1003 //Do not draw a fillet if the end points of the arc are not within the track segments
1004 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.GetP0() )
1005 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.GetP0() ) )
1006 {
1007 didOneAttemptFail = true;
1008 continue;
1009 }
1010
1011 if( !setIfPointOnSeg( t1newPoint, t1Seg, sArc.GetP1() )
1012 && !setIfPointOnSeg( t2newPoint, t2Seg, sArc.GetP1() ) )
1013 {
1014 didOneAttemptFail = true;
1015 continue;
1016 }
1017
1018 PCB_ARC* tArc = new PCB_ARC( frame()->GetBoard(), &sArc );
1019 tArc->SetLayer( track1->GetLayer() );
1020 tArc->SetWidth( track1->GetWidth() );
1021 tArc->SetNet( track1->GetNet() );
1022 tArc->SetLocked( track1->IsLocked() );
1023 m_commit->Add( tArc );
1024 itemsToAddToSelection.push_back( tArc );
1025
1026 m_commit->Modify( track1 );
1027 m_commit->Modify( track2 );
1028
1029 if( filletOp.t1Start )
1030 track1->SetStart( t1newPoint );
1031 else
1032 track1->SetEnd( t1newPoint );
1033
1034 if( filletOp.t2Start )
1035 track2->SetStart( t2newPoint );
1036 else
1037 track2->SetEnd( t2newPoint );
1038
1039 operationPerformedOnAtLeastOne = true;
1040 }
1041 }
1042
1043 m_commit->Push( _( "Fillet Tracks" ) );
1044
1045 //select the newly created arcs
1046 for( BOARD_ITEM* item : itemsToAddToSelection )
1048
1049 if( !operationPerformedOnAtLeastOne )
1050 frame()->ShowInfoBarMsg( _( "Unable to fillet the selected track segments." ) );
1051 else if( didOneAttemptFail )
1052 frame()->ShowInfoBarMsg( _( "Some of the track segments could not be filleted." ) );
1053
1054 return 0;
1055}
EDA_ITEM_FLAGS IsPointOnEnds(const VECTOR2I &point, int min_dist=0) const
Function IsPointOnEnds returns STARTPOINT if point if near (dist = min_dist) start point,...
Definition: pcb_track.cpp:236
bool Contains(EDA_ITEM *aItem) const
Definition: selection.cpp:84

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

Referenced by setTransitions().

◆ Flip()

int EDIT_TOOL::Flip ( const TOOL_EVENT aEvent)

Rotate currently selected items.

The rotation point is the current cursor position.

Definition at line 1730 of file edit_tool.cpp.

1731{
1732 if( isRouterActive() )
1733 {
1734 wxBell();
1735 return 0;
1736 }
1737
1739 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1740 {
1741 sTool->FilterCollectorForMarkers( aCollector );
1742 sTool->FilterCollectorForHierarchy( aCollector, true );
1743 sTool->FilterCollectorForFreePads( aCollector );
1744 },
1745 !m_dragging /* prompt user regarding locked items */ );
1746
1747 if( selection.Empty() )
1748 return 0;
1749
1750 std::optional<VECTOR2I> oldRefPt;
1751
1753 oldRefPt = selection.GetReferencePoint();
1754
1756
1757 // Flip around the anchor for footprints, and the bounding box center for board items
1758 VECTOR2I refPt = IsFootprintEditor() ? VECTOR2I( 0, 0 ) : selection.GetCenter();
1759
1760 // If only one item selected, flip around the selection or item anchor point (instead
1761 // of the bounding box center) to avoid moving the item anchor
1762 if( selection.GetSize() == 1 )
1763 {
1765 refPt = selection.GetReferencePoint();
1766 else
1767 refPt = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) )->GetPosition();
1768 }
1769
1770 bool leftRight = frame()->GetPcbNewSettings()->m_FlipLeftRight;
1771
1772 // When editing footprints, all items have the same parent
1773 if( IsFootprintEditor() )
1774 m_commit->Modify( selection.Front() );
1775
1776 for( EDA_ITEM* item : selection )
1777 {
1778 if( !item->IsNew() && !IsFootprintEditor() )
1779 m_commit->Modify( item );
1780
1781 if( item->Type() == PCB_GROUP_T )
1782 {
1783 static_cast<PCB_GROUP*>( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem )
1784 {
1785 m_commit->Modify( bItem );
1786 });
1787 }
1788
1789 static_cast<BOARD_ITEM*>( item )->Flip( refPt, leftRight );
1790 }
1791
1792 if( !m_dragging )
1793 m_commit->Push( _( "Change Side / Flip" ) );
1794
1795 if( selection.IsHover() && !m_dragging )
1797
1799
1800 if( m_dragging )
1802
1803 // Restore the old reference so any mouse dragging that occurs doesn't make the selection jump
1804 // to this now invalid reference
1805 if( oldRefPt )
1806 selection.SetReferencePoint( *oldRefPt );
1807 else
1809
1810 return 0;
1811}
int Flip(const TOOL_EVENT &aEvent)
Rotate currently selected items.
Definition: edit_tool.cpp:1730
bool updateModificationPoint(PCB_SELECTION &aSelection)
Definition: edit_tool.cpp:2388
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
Definition: selection.cpp:75
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:99

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

Referenced by Flip(), and setTransitions().

◆ footprint()

◆ FootprintFilter()

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

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

Definition at line 2375 of file edit_tool.cpp.

2377{
2378 for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2379 {
2380 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
2381
2382 if( item->Type() != PCB_FOOTPRINT_T )
2383 aCollector.Remove( i );
2384 }
2385}

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

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

◆ frame()

PCB_BASE_EDIT_FRAME * PCB_TOOL_BASE::frame ( ) const
inlineprotectedinherited

Definition at line 165 of file pcb_tool_base.h.

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

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

◆ GetAndPlace()

int EDIT_TOOL::GetAndPlace ( const TOOL_EVENT aEvent)

Definition at line 274 of file edit_tool.cpp.

275{
276 // GetAndPlace makes sense only in board editor, although it is also called
277 // in fpeditor, that shares the same EDIT_TOOL list
278 if( !getEditFrame<PCB_BASE_FRAME>()->IsType( FRAME_PCB_EDITOR ) )
279 return 0;
280
282 FOOTPRINT* fp = getEditFrame<PCB_BASE_FRAME>()->GetFootprintFromBoardByReference();
283
284 if( fp )
285 {
287 m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, (void*) fp );
288
289 selectionTool->GetSelection().SetReferencePoint( fp->GetPosition() );
291 }
292
293 return 0;
294}
@ FRAME_PCB_EDITOR
Definition: frame_type.h:40

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

Referenced by setTransitions().

◆ GetCurrentCommit()

BOARD_COMMIT * EDIT_TOOL::GetCurrentCommit ( ) const
inline

Definition at line 172 of file edit_tool.h.

172{ return m_commit.get(); }

References m_commit.

◆ getEditFrame()

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

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

Definition at line 185 of file tool_base.h.

186 {
187#if !defined( QA_TEST ) // Dynamic casts give the linker a seizure 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(), and ZONE_CREATE_HELPER::setUniquePriority().

◆ GetId()

TOOL_ID TOOL_BASE::GetId ( ) const
inlineinherited

Return the unique identifier of the tool.

The identifier is set by an instance of TOOL_MANAGER.

Returns
Identifier of the tool.

Definition at line 121 of file tool_base.h.

122 {
123 return m_toolId;
124 }

References TOOL_BASE::m_toolId.

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

◆ GetManager()

TOOL_MANAGER * TOOL_BASE::GetManager ( ) const
inlineinherited

◆ getModel()

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

Return the model object if it matches the requested type.

Store the type of the tool.

Definition at line 197 of file tool_base.h.

References TOOL_BASE::getModelInt().

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

◆ getModelInt()

EDA_ITEM * TOOL_BASE::getModelInt ( ) const
privateinherited

Definition at line 54 of file tool_base.cpp.

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

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

Referenced by TOOL_BASE::getModel().

◆ GetName()

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

Return the name of the tool.

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

Returns
The name of the tool.

Definition at line 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(), TOOL_MANAGER::RegisterTool(), TOOL_MANAGER::runTool(), and TOOL_MANAGER::ShutdownTool().

◆ getSafeMovement()

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

Definition at line 245 of file edit_tool_move_fct.cpp.

247{
248 typedef std::numeric_limits<int> coord_limits;
249
250 int max = coord_limits::max();
251 int min = -max;
252
253 double left = aBBoxOffset.x + aSourceBBox.GetPosition().x;
254 double top = aBBoxOffset.y + aSourceBBox.GetPosition().y;
255
256 double right = left + aSourceBBox.GetSize().x;
257 double bottom = top + aSourceBBox.GetSize().y;
258
259 // Do not restrict movement if bounding box is already out of bounds
260 if( left < min || top < min || right > max || bottom > max )
261 return aMovement;
262
263 // Constrain moving bounding box to coordinates limits
264 VECTOR2D tryMovement( aMovement );
265 VECTOR2D bBoxOrigin( aSourceBBox.GetPosition() + aBBoxOffset );
266 VECTOR2D clampedBBoxOrigin = GetClampedCoords( bBoxOrigin + tryMovement, COORDS_PADDING );
267
268 tryMovement = clampedBBoxOrigin - bBoxOrigin;
269
270 VECTOR2D bBoxEnd( aSourceBBox.GetEnd() + aBBoxOffset );
271 VECTOR2D clampedBBoxEnd = GetClampedCoords( bBoxEnd + tryMovement, COORDS_PADDING );
272
273 tryMovement = clampedBBoxEnd - bBoxEnd;
274
275 return GetClampedCoords<double, int>( tryMovement );
276}
const Vec & GetPosition() const
Definition: box2.h:184
const Vec GetEnd() const
Definition: box2.h:185
const Vec & GetSize() const
Definition: box2.h:179
static const unsigned int COORDS_PADDING
Definition: edit_tool.h:216
VECTOR2< ret_type > GetClampedCoords(const VECTOR2< in_type > &aCoords, pad_type aPadding=1u)
Clamps a vector to values that can be negated, respecting numeric limits of coordinates data type wit...

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

Referenced by doMoveSelection().

◆ getToolHolderInt()

TOOLS_HOLDER * TOOL_BASE::getToolHolderInt ( ) const
privateinherited

Definition at line 48 of file tool_base.cpp.

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

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

Referenced by TOOL_BASE::getEditFrame().

◆ GetToolMenu()

◆ GetType()

TOOL_TYPE TOOL_BASE::GetType ( ) const
inlineinherited

Return the type of the tool.

Returns
The type of the tool.

Definition at line 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}

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

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

◆ getViewControls()

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

Return the instance of VIEW_CONTROLS object used in the application.

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

Returns
The instance of VIEW_CONTROLS.

Definition at line 42 of file tool_base.cpp.

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

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

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

◆ Go()

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

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

No conditions means any event.

Definition at line 147 of file tool_interactive.h.

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

References TOOL_INTERACTIVE::goInternal().

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

◆ goInternal()

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

Definition at line 70 of file tool_interactive.cpp.

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

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

Referenced by TOOL_INTERACTIVE::Go().

◆ Init()

bool EDIT_TOOL::Init ( )
overridevirtual

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

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

Reimplemented from PCB_TOOL_BASE.

Definition at line 105 of file edit_tool.cpp.

106{
107 // Find the selection tool, so they can cooperate
109
110 auto positioningToolsSubMenu = std::make_shared<POSITIONING_TOOLS_MENU>( this );
111 m_selectionTool->GetToolMenu().RegisterSubMenu( positioningToolsSubMenu );
112
113 auto propertiesCondition =
114 [&]( const SELECTION& aSel )
115 {
116 if( aSel.GetSize() == 0 )
117 {
119 {
122
123 if( ds && ds->HitTestDrawingSheetItems( getView(), cursor ) )
124 return true;
125 }
126
127 return false;
128 }
129
130 if( aSel.GetSize() == 1 )
131 return true;
132
133 for( EDA_ITEM* item : aSel )
134 {
135 if( !dynamic_cast<PCB_TRACK*>( item ) )
136 return false;
137 }
138
139 return true;
140 };
141
142 auto inFootprintEditor =
143 [ this ]( const SELECTION& aSelection )
144 {
145 return m_isFootprintEditor;
146 };
147
148 auto canMirror =
149 [ this ]( const SELECTION& aSelection )
150 {
152 && SELECTION_CONDITIONS::OnlyTypes( { PCB_PAD_T } )( aSelection ) )
153 {
154 return false;
155 }
156
158 };
159
160 auto singleFootprintCondition = SELECTION_CONDITIONS::OnlyTypes( { PCB_FOOTPRINT_T } )
162
163 auto noActiveToolCondition =
164 [ this ]( const SELECTION& aSelection )
165 {
166 return frame()->ToolStackIsEmpty();
167 };
168
169 auto notMovingCondition =
170 [ this ]( const SELECTION& aSelection )
171 {
175 };
176
177 auto noItemsCondition =
178 [ this ]( const SELECTION& aSelections ) -> bool
179 {
180 return frame()->GetBoard() && !frame()->GetBoard()->IsEmpty();
181 };
182
183 auto isSkippable =
184 [ this ]( const SELECTION& aSelection )
185 {
187 };
188
189 static std::vector<KICAD_T> connectedTypes = { PCB_TRACE_T,
190 PCB_ARC_T,
191 PCB_VIA_T,
192 PCB_PAD_T,
193 PCB_ZONE_T };
194
195 static std::vector<KICAD_T> unroutableTypes = { PCB_TRACE_T,
196 PCB_ARC_T,
197 PCB_VIA_T,
198 PCB_PAD_T,
200
201 static std::vector<KICAD_T> trackTypes = { PCB_TRACE_T,
202 PCB_ARC_T,
203 PCB_VIA_T };
204
205 static std::vector<KICAD_T> filletTypes = { PCB_SHAPE_LOCATE_POLY_T,
208
209
210 // Add context menu entries that are displayed when selection tool is active
212
214 && notMovingCondition );
216 && SELECTION_CONDITIONS::OnlyTypes( unroutableTypes )
217 && notMovingCondition
218 && !inFootprintEditor );
220 && notMovingCondition );
221 menu.AddItem( PCB_ACTIONS::skip, isSkippable );
223 && SELECTION_CONDITIONS::OnlyTypes( trackTypes ) );
234 menu.AddItem( PCB_ACTIONS::mirrorH, canMirror );
235 menu.AddItem( PCB_ACTIONS::mirrorV, canMirror );
239
240 menu.AddItem( PCB_ACTIONS::properties, propertiesCondition );
241
243 && !inFootprintEditor );
245
246 // Footprint actions
247 menu.AddSeparator();
248 menu.AddItem( PCB_ACTIONS::editFpInFpEditor, singleFootprintCondition );
249 menu.AddItem( PCB_ACTIONS::updateFootprint, singleFootprintCondition );
250 menu.AddItem( PCB_ACTIONS::changeFootprint, singleFootprintCondition );
251
252 // Add the submenu for the special positioning tools
253 menu.AddSeparator( 100 );
254 menu.AddMenu( positioningToolsSubMenu.get(), SELECTION_CONDITIONS::NotEmpty, 100 );
255
256 menu.AddSeparator( 150 );
259
260 // Selection tool handles the context menu for some other tools, such as the Picker.
261 // Don't add things like Paste when another tool is active.
262 menu.AddItem( ACTIONS::paste, noActiveToolCondition, 150 );
263 menu.AddItem( ACTIONS::pasteSpecial, noActiveToolCondition && !inFootprintEditor, 150 );
266
267 menu.AddSeparator( 150 );
268 menu.AddItem( ACTIONS::selectAll, noItemsCondition, 150 );
269
270 return true;
271}
static TOOL_ACTION paste
Definition: actions.h:69
static TOOL_ACTION copy
Definition: actions.h:68
static TOOL_ACTION pasteSpecial
Definition: actions.h:70
static TOOL_ACTION selectAll
Definition: actions.h:71
bool IsEmpty() const
Definition: board.h:361
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
bool HitTestDrawingSheetItems(KIGFX::VIEW *aView, const VECTOR2I &aPosition)
static const std::vector< KICAD_T > MirrorableItems
Definition: edit_tool.h:114
static const std::vector< KICAD_T > DraggableItems
A scan list for items that can be dragged.
Definition: collectors.h:270
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
static TOOL_ACTION drag45Degree
Definition: pcb_actions.h:166
static TOOL_ACTION unrouteSelected
Removes all tracks from the selected items to the first pad.
Definition: pcb_actions.h:83
static TOOL_ACTION updateFootprint
Definition: pcb_actions.h:364
static TOOL_ACTION breakTrack
Break a single track into two segments at the cursor.
Definition: pcb_actions.h:164
static TOOL_ACTION editFpInFpEditor
Definition: pcb_actions.h:386
static TOOL_ACTION swap
Swapping of selected items.
Definition: pcb_actions.h:133
static TOOL_ACTION assignNetClass
Definition: pcb_actions.h:340
static TOOL_ACTION packAndMoveFootprints
Pack and start moving selected footprints.
Definition: pcb_actions.h:136
static TOOL_ACTION inspectClearance
Definition: pcb_actions.h:492
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:145
static TOOL_ACTION filletLines
Definition: pcb_actions.h:146
static TOOL_ACTION changeFootprint
Definition: pcb_actions.h:366
DS_PROXY_VIEW_ITEM * GetDrawingSheet() const
static SELECTION_CONDITION HasTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if among the selected items there is at least one of a given types.
static SELECTION_CONDITION HasType(KICAD_T aType)
Create a functor that tests if among the selected items there is at least one of a given type.
static bool NotEmpty(const SELECTION &aSelection)
Test if there are any items selected.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
bool ToolStackIsEmpty()
Definition: tools_holder.h:128
bool IsCurrentTool(const TOOL_ACTION &aAction) const
TOOL_MENU & GetToolMenu()
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
void RegisterSubMenu(std::shared_ptr< ACTION_MENU > aSubMenu)
Store a submenu of this menu model.
Definition: tool_menu.cpp:50
static std::vector< KICAD_T > connectedTypes
@ LAYER_SCHEMATIC_DRAWINGSHEET
Definition: layer_ids.h:382
@ PCB_SHAPE_LOCATE_RECT_T
Definition: typeinfo.h:132
@ PCB_SHAPE_LOCATE_POLY_T
Definition: typeinfo.h:135

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

◆ invokeInlineRouter()

bool EDIT_TOOL::invokeInlineRouter ( int  aDragMode)
private

Definition at line 297 of file edit_tool.cpp.

298{
300
301 if( !theRouter )
302 return false;
303
304 // don't allow switch from moving to dragging
305 if( m_dragging )
306 {
307 wxBell();
308 return false;
309 }
310
311 // make sure we don't accidentally invoke inline routing mode while the router is already
312 // active!
313 if( theRouter->IsToolActive() )
314 return false;
315
316 if( theRouter->CanInlineDrag( aDragMode ) )
317 {
319 static_cast<intptr_t>( aDragMode ) );
320 return true;
321 }
322
323 return false;
324}
static TOOL_ACTION routerInlineDrag
Activation of the Push and Shove router (inline dragging mode)
Definition: pcb_actions.h:242
static ROUTER * theRouter
Definition: pns_router.cpp:58

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

◆ Is45Limited()

bool PCB_TOOL_BASE::Is45Limited ( ) const
virtualinherited

Should the tool use its 45° mode option?

Returns
True if set to use 45°

Definition at line 332 of file pcb_tool_base.cpp.

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

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

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

◆ IsBoardEditor()

bool PCB_TOOL_BASE::IsBoardEditor ( ) const
inlineinherited

Definition at line 109 of file pcb_tool_base.h.

109{ return m_isBoardEditor; }

References PCB_TOOL_BASE::m_isBoardEditor.

Referenced by BOARD_COMMIT::BOARD_COMMIT().

◆ IsFootprintEditor()

bool PCB_TOOL_BASE::IsFootprintEditor ( ) const
inlineinherited

◆ isRouterActive()

bool EDIT_TOOL::isRouterActive ( ) const
private

Definition at line 327 of file edit_tool.cpp.

328{
330
331 return router && router->RoutingInProgress();
332}
bool RoutingInProgress()
Returns whether routing is currently active.

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

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

◆ IsToolActive()

bool TOOL_BASE::IsToolActive ( ) const
inherited

Definition at line 31 of file tool_base.cpp.

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

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

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

◆ Mirror()

int EDIT_TOOL::Mirror ( const TOOL_EVENT aEvent)

Mirror the current selection.

The mirror axis passes through the current point.

Definition at line 1617 of file edit_tool.cpp.

1618{
1619 if( isRouterActive() )
1620 {
1621 wxBell();
1622 return 0;
1623 }
1624
1626 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1627 {
1628 sTool->FilterCollectorForMarkers( aCollector );
1629 sTool->FilterCollectorForHierarchy( aCollector, true );
1630 sTool->FilterCollectorForFreePads( aCollector );
1631 },
1632 !m_dragging /* prompt user regarding locked items */ );
1633
1634 if( selection.Empty() )
1635 return 0;
1636
1638 VECTOR2I mirrorPoint = selection.GetReferencePoint();
1639
1640 // When editing footprints, all items have the same parent
1641 if( IsFootprintEditor() )
1642 m_commit->Modify( selection.Front() );
1643
1644 // Set the mirroring options.
1645 // Unfortunately, the mirror function do not have the same parameter for all items
1646 // So we need these 2 parameters to avoid mistakes
1647 bool mirrorLeftRight = true;
1648 bool mirrorAroundXaxis = false;
1649
1650 if( aEvent.IsAction( &PCB_ACTIONS::mirrorV ) )
1651 {
1652 mirrorLeftRight = false;
1653 mirrorAroundXaxis = true;
1654 }
1655
1656 for( EDA_ITEM* item : selection )
1657 {
1658 if( !item->IsType( MirrorableItems ) )
1659 continue;
1660
1661 if( !item->IsNew() && !IsFootprintEditor() )
1662 m_commit->Modify( item );
1663
1664 // modify each object as necessary
1665 switch( item->Type() )
1666 {
1667 case PCB_FP_SHAPE_T:
1668 case PCB_SHAPE_T:
1669 static_cast<PCB_SHAPE*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1670 break;
1671
1672 case PCB_FP_ZONE_T:
1673 case PCB_ZONE_T:
1674 static_cast<FP_ZONE*>( item )->Mirror( mirrorPoint, mirrorLeftRight );
1675 break;
1676
1677 case PCB_FP_TEXT_T:
1678 static_cast<FP_TEXT*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1679 break;
1680
1681 case PCB_TEXT_T:
1682 static_cast<PCB_TEXT*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1683 break;
1684
1685 case PCB_FP_TEXTBOX_T:
1686 static_cast<FP_TEXTBOX*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1687 break;
1688
1689 case PCB_TEXTBOX_T:
1690 static_cast<PCB_TEXTBOX*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1691 break;
1692
1693 case PCB_PAD_T:
1694 if( mirrorLeftRight )
1695 mirrorPadX( *static_cast<PAD*>( item ), mirrorPoint );
1696 else
1697 mirrorPadY( *static_cast<PAD*>( item ), mirrorPoint );
1698
1699 break;
1700
1701 case PCB_TRACE_T:
1702 case PCB_ARC_T:
1703 case PCB_VIA_T:
1704 static_cast<PCB_TRACK*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
1705 break;
1706
1707 default:
1708 // it's likely the commit object is wrong if you get here
1709 // Unsure if PCB_GROUP_T needs special attention here.
1710 assert( false );
1711 break;
1712 }
1713 }
1714
1715 if( !m_dragging )
1716 m_commit->Push( _( "Mirror" ) );
1717
1718 if( selection.IsHover() && !m_dragging )
1720
1722
1723 if( m_dragging )
1725
1726 return 0;
1727}
int Mirror(const TOOL_EVENT &aEvent)
Mirror the current selection.
Definition: edit_tool.cpp:1617
static void mirrorPadX(PAD &aPad, const VECTOR2I &aMirrorPoint)
Mirror a pad in the vertical axis passing through a point (mirror left to right).
Definition: edit_tool.cpp:1555
static void mirrorPadY(PAD &aPad, const VECTOR2I &aMirrorPoint)
Mirror a pad in the vertical axis passing through a point (mirror left to right).
Definition: edit_tool.cpp:1580
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94

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

Referenced by Mirror(), and setTransitions().

◆ Move()

int EDIT_TOOL::Move ( const TOOL_EVENT aEvent)

Main loop in which events are handled.

Definition at line 233 of file edit_tool_move_fct.cpp.

234{
235 if( isRouterActive() )
236 {
237 wxBell();
238 return 0;
239 }
240
241 return doMoveSelection( aEvent, _( "Move" ) );
242}
int doMoveSelection(const TOOL_EVENT &aEvent, const wxString &aCommitMessage)

References _, doMoveSelection(), and isRouterActive().

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

◆ MoveExact()

int EDIT_TOOL::MoveExact ( const TOOL_EVENT aEvent)

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

Definition at line 2087 of file edit_tool.cpp.

2088{
2089 if( isRouterActive() )
2090 {
2091 wxBell();
2092 return 0;
2093 }
2094
2096 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2097 {
2098 sTool->FilterCollectorForMarkers( aCollector );
2099 sTool->FilterCollectorForHierarchy( aCollector, true );
2100 },
2101 true /* prompt user regarding locked items */ );
2102
2103 if( selection.Empty() )
2104 return 0;
2105
2106 VECTOR2I translation;
2107 EDA_ANGLE rotation;
2110
2111 // TODO: Implement a visible bounding border at the edge
2112 BOX2I sel_box = selection.GetBoundingBox();
2113
2114 DIALOG_MOVE_EXACT dialog( frame(), translation, rotation, rotationAnchor, sel_box );
2115 int ret = dialog.ShowModal();
2116
2117 if( ret == wxID_OK )
2118 {
2119 EDA_ANGLE angle = rotation;
2121 VECTOR2I selCenter( rp.x, rp.y );
2122
2123 // Make sure the rotation is from the right reference point
2124 selCenter += translation;
2125
2126 if( !frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
2127 rotation = -rotation;
2128
2129 // When editing footprints, all items have the same parent
2130 if( IsFootprintEditor() )
2131 m_commit->Modify( selection.Front() );
2132
2133 for( EDA_ITEM* selItem : selection )
2134 {
2135 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selItem );
2136
2137 if( !item->IsNew() && !IsFootprintEditor() )
2138 {
2139 m_commit->Modify( item );
2140
2141 if( item->Type() == PCB_GROUP_T )
2142 {
2143 PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
2144
2145 group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
2146 {
2147 m_commit->Modify( bItem );
2148 });
2149 }
2150 }
2151
2152 if( !item->GetParent() || !item->GetParent()->IsSelected() )
2153 item->Move( translation );
2154
2155 switch( rotationAnchor )
2156 {
2158 item->Rotate( item->GetPosition(), angle );
2159 break;
2161 item->Rotate( selCenter, angle );
2162 break;
2164 item->Rotate( frame()->GetScreen()->m_LocalOrigin, angle );
2165 break;
2168 break;
2169 }
2170
2171 if( !m_dragging )
2172 getView()->Update( item );
2173 }
2174
2175 m_commit->Push( _( "Move exact" ) );
2176
2177 if( selection.IsHover() )
2179
2181
2182 if( m_dragging )
2184 }
2185
2186 return 0;
2187}
VECTOR2D m_LocalOrigin
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:90
const VECTOR2I & GetAuxOrigin()
virtual void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
Rotate this object.
Definition: board_item.cpp:250
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
virtual VECTOR2I GetCenter() const
Returns the center point of the selection area bounding box.
Definition: selection.cpp:93
virtual BOX2I GetBoundingBox() const
Definition: selection.cpp:133
ROTATION_ANCHOR
@ ROTATE_AROUND_USER_ORIGIN
@ ROTATE_AROUND_SEL_CENTER
@ ROTATE_AROUND_AUX_ORIGIN
@ ROTATE_AROUND_ITEM_ANCHOR
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

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

Referenced by setTransitions().

◆ PackAndMoveFootprints()

int EDIT_TOOL::PackAndMoveFootprints ( const TOOL_EVENT aEvent)

Try to fit selected footprints inside a minimal area and start movement.

Definition at line 191 of file edit_tool_move_fct.cpp.

192{
194 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
195 {
196 sTool->FilterCollectorForMarkers( aCollector );
197 sTool->FilterCollectorForHierarchy( aCollector, true );
198 sTool->FilterCollectorForFreePads( aCollector );
199
200 // Iterate from the back so we don't have to worry about removals.
201 for( int i = aCollector.GetCount() - 1; i >= 0; --i )
202 {
203 BOARD_ITEM* item = aCollector[i];
204
205 if( !dynamic_cast<FOOTPRINT*>( item ) )
206 aCollector.Remove( item );
207 }
208 },
209 true /* prompt user regarding locked items */ );
210
211 std::vector<FOOTPRINT*> footprintsToPack;
212
213 for( EDA_ITEM* item : selection )
214 footprintsToPack.push_back( static_cast<FOOTPRINT*>( item ) );
215
216 if( footprintsToPack.empty() )
217 return 0;
218
219 BOX2I footprintsBbox;
220
221 for( FOOTPRINT* item : footprintsToPack )
222 {
223 m_commit->Modify( item );
224 footprintsBbox.Merge( item->GetBoundingBox( false, false ) );
225 }
226
227 SpreadFootprints( &footprintsToPack, footprintsBbox.Normalize().GetOrigin(), false );
228
229 return doMoveSelection( aEvent, _( "Pack footprints" ) );
230}
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:119
const Vec & GetOrigin() const
Definition: box2.h:183
void SpreadFootprints(std::vector< FOOTPRINT * > *aFootprints, VECTOR2I aTargetBoxPosition, bool aGroupBySheet, int aComponentGap, int aGroupGap)
Footprints (after loaded by reading a netlist for instance) are moved to be in a small free area (out...

References _, doMoveSelection(), PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::FilterCollectorForHierarchy(), PCB_SELECTION_TOOL::FilterCollectorForMarkers(), COLLECTOR::GetCount(), BOX2< Vec >::GetOrigin(), m_commit, m_selectionTool, BOX2< Vec >::Merge(), BOX2< Vec >::Normalize(), PCB_SELECTION_TOOL::RequestSelection(), PCB_TOOL_BASE::selection(), and SpreadFootprints().

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

2364{
2365 for( int i = aCollector.GetCount() - 1; i >= 0; i-- )
2366 {
2367 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( aCollector[i] );
2368
2369 if( item->Type() != PCB_PAD_T )
2370 aCollector.Remove( i );
2371 }
2372}

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

Rebuilds the ratsnest for operations that require it outside the commit rebuild.

This allow the option of snapping in the tool

Definition at line 2415 of file edit_tool.cpp.

2417{
2419 std::optional<VECTOR2I> pickedPoint;
2420 bool done = false;
2421
2422 m_statusPopup->SetText( aTooltip );
2423
2425 picker->SetSnapping( true );
2426
2427 picker->SetClickHandler(
2428 [&]( const VECTOR2D& aPoint ) -> bool
2429 {
2430 pickedPoint = aPoint;
2431
2432 if( !aSuccessMessage.empty() )
2433 {
2434 m_statusPopup->SetText( aSuccessMessage );
2435 m_statusPopup->Expire( 800 );
2436 }
2437 else
2438 {
2439 m_statusPopup->Hide();
2440 }
2441
2442 return false; // we don't need any more points
2443 } );
2444
2445 picker->SetMotionHandler(
2446 [&]( const VECTOR2D& aPos )
2447 {
2448 m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
2449 } );
2450
2451 picker->SetCancelHandler(
2452 [&]()
2453 {
2454 if( !aCanceledMessage.empty() )
2455 {
2456 m_statusPopup->SetText( aCanceledMessage );
2457 m_statusPopup->Expire( 800 );
2458 }
2459 else
2460 {
2461 m_statusPopup->Hide();
2462 }
2463 } );
2464
2465 picker->SetFinalizeHandler(
2466 [&]( const int& aFinalState )
2467 {
2468 done = true;
2469 } );
2470
2471 m_statusPopup->Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
2472 m_statusPopup->Popup();
2473 canvas()->SetStatusPopup( m_statusPopup->GetPanel() );
2474
2476
2477 while( !done )
2478 {
2479 // Pass events unless we receive a null event, then we must shut down
2480 if( TOOL_EVENT* evt = Wait() )
2481 evt->SetPassEvent();
2482 else
2483 break;
2484 }
2485
2486 // Ensure statusPopup is hidden after use and before deleting it:
2487 canvas()->SetStatusPopup( nullptr );
2488 m_statusPopup->Hide();
2489
2490 if( pickedPoint )
2491 aReferencePoint = *pickedPoint;
2492
2493 return pickedPoint.has_value();
2494}
static TOOL_ACTION pickerSubTool
Definition: actions.h:160
std::unique_ptr< STATUS_TEXT_POPUP > m_statusPopup
Definition: edit_tool.h:214
Generic tool for picking an item.
void SetMotionHandler(MOTION_HANDLER aHandler)
Set a handler for mouse motion.
Definition: picker_tool.h:82
void SetClickHandler(CLICK_HANDLER aHandler)
Set a handler for mouse click event.
Definition: picker_tool.h:71
void SetSnapping(bool aSnap)
Definition: picker_tool.h:64
void SetCancelHandler(CANCEL_HANDLER aHandler)
Set a handler for cancel events (ESC or context-menu Cancel).
Definition: picker_tool.h:91
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Set a handler for the finalize event.
Definition: picker_tool.h:102

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

Referenced by copyToClipboard(), and doMoveSelection().

◆ Properties()

int EDIT_TOOL::Properties ( const TOOL_EVENT aEvent)

Display properties window for the selected object.

Definition at line 1338 of file edit_tool.cpp.

1339{
1340 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1342 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1343 {
1344 } );
1345
1346 // Tracks & vias are treated in a special way:
1348 {
1350 dlg.ShowQuasiModal(); // QuasiModal required for NET_SELECTOR
1351 }
1352 else if( selection.Size() == 1 )
1353 {
1354 // Display properties dialog
1355 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( selection.Front() );
1356
1357 // Do not handle undo buffer, it is done by the properties dialogs
1358 editFrame->OnEditItemRequest( item );
1359
1360 // Notify other tools of the changes
1362 }
1363 else if( selection.Size() == 0 && getView()->IsLayerVisible( LAYER_DRAWINGSHEET ) )
1364 {
1365 DS_PROXY_VIEW_ITEM* ds = editFrame->GetCanvas()->GetDrawingSheet();
1366 VECTOR2D cursorPos = getViewControls()->GetCursorPosition( false );
1367
1368 if( ds && ds->HitTestDrawingSheetItems( getView(), cursorPos ) )
1370 else
1372 }
1373
1374 if( selection.IsHover() )
1375 {
1377 }
1378 else
1379 {
1380 // Check for items becoming invisible and drop them from the selection.
1381
1382 PCB_SELECTION selCopy = selection;
1383 LSET visible = editFrame->GetBoard()->GetVisibleLayers();
1384
1385 for( EDA_ITEM* eda_item : selCopy )
1386 {
1387 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( eda_item );
1388
1389 if( !( item->GetLayerSet() & visible ).any() )
1391 }
1392 }
1393
1394 return 0;
1395}
static TOOL_ACTION pageSettings
Definition: actions.h:56
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:197
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:601
static TOOL_ACTION footprintProperties
Definition: pcb_actions.h:420
@ LAYER_DRAWINGSHEET
drawingsheet frame and titleblock
Definition: layer_ids.h:217

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

Referenced by setTransitions().

◆ rebuildConnectivity()

void EDIT_TOOL::rebuildConnectivity ( )
private

Definition at line 2583 of file edit_tool.cpp.

2584{
2588}
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition: board.cpp:166
static const TOOL_EVENT ConnectivityChangedEvent
Selected item had a property changed (except movement)
Definition: actions.h:211
void RedrawRatsnest()
Return the bounding box of the view that should be used if model is not valid.

References PCB_TOOL_BASE::board(), BOARD::BuildConnectivity(), PCB_TOOL_BASE::canvas(), EVENTS::ConnectivityChangedEvent, TOOL_BASE::m_toolMgr, TOOL_MANAGER::PostEvent(), and PCB_DRAW_PANEL_GAL::RedrawRatsnest().

Referenced by doMoveSelection().

◆ Remove()

int EDIT_TOOL::Remove ( const TOOL_EVENT aEvent)

Delete currently selected items.

Definition at line 2009 of file edit_tool.cpp.

2010{
2011 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
2012
2013 if( isRouterActive() )
2014 {
2016 return 0;
2017 }
2018
2019 editFrame->PushTool( aEvent );
2020
2021 std::vector<BOARD_ITEM*> lockedItems;
2022 Activate();
2023
2024 // get a copy instead of reference (as we're going to clear the selection before removing items)
2025 PCB_SELECTION selectionCopy;
2028
2029 // If we are in a "Cut" operation, then the copied selection exists already and we want to
2030 // delete exactly that; no more, no fewer. Any filtering for locked items must be done in
2031 // the copyToClipboard() routine.
2032 if( isCut )
2033 {
2034 selectionCopy = m_selectionTool->GetSelection();
2035 }
2036 else
2037 {
2038 // When not in free-pad mode we normally auto-promote selected pads to their parent
2039 // footprints. But this is probably a little too dangerous for a destructive operation,
2040 // so we just do the promotion but not the deletion (allowing for a second delete to do
2041 // it if that's what the user wanted).
2042 selectionCopy = m_selectionTool->RequestSelection(
2043 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2044 {
2045 } );
2046
2047 size_t beforeFPCount = selectionCopy.CountType( PCB_FOOTPRINT_T );
2048
2050 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2051 {
2052 sTool->FilterCollectorForFreePads( aCollector );
2053 } );
2054
2055 if( !selectionCopy.IsHover()
2056 && m_selectionTool->GetSelection().CountType( PCB_FOOTPRINT_T ) > beforeFPCount )
2057 {
2058 wxBell();
2059 canvas()->Refresh();
2060 editFrame->PopTool( aEvent );
2061 return 0;
2062 }
2063
2064 // In "alternative" mode, we expand selected track items to their full connection.
2065 if( isAlt && ( selectionCopy.HasType( PCB_TRACE_T ) || selectionCopy.HasType( PCB_VIA_T ) ) )
2066 {
2068 }
2069
2070 // Finally run RequestSelection() one more time to find out what user wants to do about
2071 // locked objects.
2072 selectionCopy = m_selectionTool->RequestSelection(
2073 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
2074 {
2075 sTool->FilterCollectorForFreePads( aCollector );
2076 },
2077 true /* prompt user regarding locked items */ );
2078 }
2079
2080 DeleteItems( selectionCopy, isCut );
2081
2082 editFrame->PopTool( aEvent );
2083 return 0;
2084}
REMOVE_FLAGS
Definition: actions.h:196
void DeleteItems(const PCB_SELECTION &aItems, bool aIsCut)
Definition: edit_tool.cpp:1814
static TOOL_ACTION routerUndoLastSegment
Definition: pcb_actions.h:222
static TOOL_ACTION selectConnection
Select tracks between junctions or expands an existing selection to pads or the entire connection.
Definition: pcb_actions.h:80
bool HasType(KICAD_T aType) const
Checks if there is at least one item of requested kind.
Definition: selection.cpp:144

References TOOL_INTERACTIVE::Activate(), ACTIONS::ALT, PCB_TOOL_BASE::canvas(), SELECTION::CountType(), ACTIONS::CUT, DeleteItems(), PCB_SELECTION_TOOL::FilterCollectorForFreePads(), PCB_SELECTION_TOOL::GetSelection(), SELECTION::HasType(), SELECTION::IsHover(), isRouterActive(), m_selectionTool, TOOL_BASE::m_toolMgr, TOOL_EVENT::Parameter(), PCB_FOOTPRINT_T, PCB_TRACE_T, PCB_VIA_T, TOOLS_HOLDER::PopTool(), TOOLS_HOLDER::PushTool(), EDA_DRAW_PANEL_GAL::Refresh(), PCB_SELECTION_TOOL::RequestSelection(), PCB_ACTIONS::routerUndoLastSegment, TOOL_MANAGER::RunAction(), and PCB_ACTIONS::selectConnection.

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

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

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

◆ resetTransitions()

void TOOL_INTERACTIVE::resetTransitions ( )
privateinherited

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

Definition at line 63 of file tool_interactive.cpp.

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

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

◆ Rotate()

int EDIT_TOOL::Rotate ( const TOOL_EVENT aEvent)

Rotate currently selected items.

Definition at line 1398 of file edit_tool.cpp.

1399{
1400 if( isRouterActive() )
1401 {
1402 wxBell();
1403 return 0;
1404 }
1405
1406 PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
1407
1408 // Be sure that there is at least one item that we can modify. If nothing was selected before,
1409 // try looking for the stuff under mouse cursor (i.e. KiCad old-style hover selection)
1411 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1412 {
1413 sTool->FilterCollectorForHierarchy( aCollector, true );
1414 sTool->FilterCollectorForMarkers( aCollector );
1415 },
1416 // Prompt user regarding locked items if in board editor and in free-pad-mode (if
1417 // we're not in free-pad mode we delay this until the second RequestSelection()).
1419
1420 if( selection.Empty() )
1421 return 0;
1422
1423 std::optional<VECTOR2I> oldRefPt;
1424 bool is_hover = selection.IsHover(); // N.B. This must be saved before the second
1425 // call to RequestSelection() below
1426
1428 oldRefPt = selection.GetReferencePoint();
1429
1430 // Now filter out pads if not in free pads mode. We cannot do this in the first
1431 // RequestSelection() as we need the reference point when a pad is the selection front.
1433 {
1435 []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
1436 {
1437 sTool->FilterCollectorForMarkers( aCollector );
1438 sTool->FilterCollectorForHierarchy( aCollector, true );
1439 sTool->FilterCollectorForFreePads( aCollector );
1440 },
1441 true /* prompt user regarding locked items */ );
1442 }
1443
1444 // Did we filter everything out? If so, don't try to operate further
1445 if( selection.Empty() )
1446 return 0;
1447
1449
1451 EDA_ANGLE rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
1452
1453 // Calculate view bounding box
1454 BOX2I viewBBox = selection.Front()->ViewBBox();
1455
1456 for( EDA_ITEM* item : selection )
1457 viewBBox.Merge( item->ViewBBox() );
1458
1459 // Check if the view bounding box will go out of bounds
1460 VECTOR2D rotPos = viewBBox.GetPosition();
1461 VECTOR2D rotEnd = viewBBox.GetEnd();
1462
1463 RotatePoint( &rotPos.x, &rotPos.y, refPt.x, refPt.y, rotateAngle );
1464 RotatePoint( &rotEnd.x, &rotEnd.y, refPt.x, refPt.y, rotateAngle );
1465
1466 typedef std::numeric_limits<int> coord_limits;
1467
1468 int max = coord_limits::max() - COORDS_PADDING;
1469 int min = -max;
1470
1471 bool outOfBounds = rotPos.x < min || rotPos.x > max || rotPos.y < min || rotPos.y > max
1472 || rotEnd.x < min || rotEnd.x > max || rotEnd.y < min || rotEnd.y > max;
1473
1474 if( !outOfBounds )
1475 {
1476 // When editing footprints, all items have the same parent
1477 if( IsFootprintEditor() )
1478 m_commit->Modify( selection.Front() );
1479
1480 for( EDA_ITEM* item : selection )
1481 {
1482 if( !item->IsNew() && !IsFootprintEditor() )
1483 {
1484 m_commit->Modify( item );
1485
1486 // If rotating a group, record position of all the descendants for undo
1487 if( item->Type() == PCB_GROUP_T )
1488 {
1489 static_cast<PCB_GROUP*>( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem )
1490 {
1491 m_commit->Modify( bItem );
1492 });
1493 }
1494 }
1495
1496 static_cast<BOARD_ITEM*>( item )->Rotate( refPt, rotateAngle );
1497 }
1498
1499 if( !m_dragging )
1500 m_commit->Push( _( "Rotate" ) );
1501
1502 if( is_hover && !m_dragging )
1504
1506
1507 if( m_dragging )
1509 }
1510
1511 // Restore the old reference so any mouse dragging that occurs doesn't make the selection jump
1512 // to this now invalid reference
1513 if( oldRefPt )
1514 selection.SetReferencePoint( *oldRefPt );
1515 else
1517
1518 return 0;
1519}
int Rotate(const TOOL_EVENT &aEvent)
Rotate currently selected items.
Definition: edit_tool.cpp:1398
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183

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

Referenced by Rotate(), and setTransitions().

◆ RunMainStack()

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

Call a function using the main stack.

Parameters
aFuncis the function to be calls.

Definition at line 87 of file tool_interactive.cpp.

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

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

Referenced by DRAWING_TOOL::PlaceText().

◆ selection() [1/2]

PCB_SELECTION & PCB_TOOL_BASE::selection ( )
protectedinherited

Definition at line 324 of file pcb_tool_base.cpp.

325{
327
328 return selTool->GetSelection();
329}

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

◆ selection() [2/2]

const PCB_SELECTION & PCB_TOOL_BASE::selection ( ) const
protectedinherited

Definition at line 316 of file pcb_tool_base.cpp.

317{
319
320 return selTool->GetSelection();
321}

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

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

◆ SetContextMenu()

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

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

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

Definition at line 76 of file tool_interactive.cpp.

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

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

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

◆ SetIsBoardEditor()

void PCB_TOOL_BASE::SetIsBoardEditor ( bool  aEnabled)
inlineinherited

Definition at line 108 of file pcb_tool_base.h.

108{ m_isBoardEditor = aEnabled; }

References PCB_TOOL_BASE::m_isBoardEditor.

◆ SetIsFootprintEditor()

void PCB_TOOL_BASE::SetIsFootprintEditor ( bool  aEnabled)
inlineinherited

Function SetIsFootprintEditor()

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

Parameters
aEnableddecides if the mode should be enabled.

Definition at line 105 of file pcb_tool_base.h.

105{ m_isFootprintEditor = aEnabled; }

References PCB_TOOL_BASE::m_isFootprintEditor.

◆ setTransitions()

void EDIT_TOOL::setTransitions ( )
overrideprivatevirtual

< Set up handlers for various events.

Reimplemented from PCB_TOOL_BASE.

Definition at line 2591 of file edit_tool.cpp.

2592{
2594 Go( &EDIT_TOOL::Move, PCB_ACTIONS::move.MakeEvent() );
2600 Go( &EDIT_TOOL::Flip, PCB_ACTIONS::flip.MakeEvent() );
2601 Go( &EDIT_TOOL::Remove, ACTIONS::doDelete.MakeEvent() );
2609 Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirrorH.MakeEvent() );
2610 Go( &EDIT_TOOL::Mirror, PCB_ACTIONS::mirrorV.MakeEvent() );
2611 Go( &EDIT_TOOL::Swap, PCB_ACTIONS::swap.MakeEvent() );
2616
2619 Go( &EDIT_TOOL::cutToClipboard, ACTIONS::cut.MakeEvent() );
2620}