KiCad PCB EDA Suite
DRAWING_TOOL Class Reference

Tool responsible for drawing graphical elements like lines, arcs, circles, etc. More...

#include <drawing_tool.h>

Inheritance diagram for DRAWING_TOOL:
PCB_TOOL_BASE TOOL_INTERACTIVE TOOL_BASE

Public Types

enum class  MODE {
  NONE , LINE , RECTANGLE , CIRCLE ,
  ARC , IMAGE , TEXT , ANCHOR ,
  DXF , DIMENSION , KEEPOUT , ZONE ,
  GRAPHIC_POLYGON , VIA
}
 
enum  RESET_REASON { RUN , MODEL_RELOAD , GAL_SWITCH , REDRAW }
 Determine the reason of reset for a tool. More...
 

Public Member Functions

 DRAWING_TOOL ()
 
 ~DRAWING_TOOL ()
 
bool Init () override
 Init() is called once upon a registration of the tool. More...
 
void Reset (RESET_REASON aReason) override
 Bring the tool to a known, initial state. More...
 
MODE GetDrawingMode () const
 Return the current drawing mode of the DRAWING_TOOL or #MODE::NONE if not currently in any drawing mode. More...
 
std::vector< BOARD_ITEM * > DrawBoardCharacteristics (const VECTOR2I &origin, PCB_LAYER_ID aLayer, bool aDrawNow, VECTOR2I *tablesize)
 
std::vector< BOARD_ITEM * > DrawSpecificationStackup (const VECTOR2I &origin, PCB_LAYER_ID aLayer, bool aDrawNow, VECTOR2I *tablesize)
 
int PlaceCharacteristics (const TOOL_EVENT &aEvent)
 
int PlaceStackup (const TOOL_EVENT &aEvent)
 
int DrawLine (const TOOL_EVENT &aEvent)
 Start interactively drawing a line. More...
 
int DrawRectangle (const TOOL_EVENT &aEvent)
 Start interactively drawing a rectangle. More...
 
int DrawCircle (const TOOL_EVENT &aEvent)
 Start interactively drawing a circle. More...
 
int DrawArc (const TOOL_EVENT &aEvent)
 Start interactively drawing an arc. More...
 
int PlaceImage (const TOOL_EVENT &aEvent)
 Display a dialog that allows one to select and image then decide where to place the image in the editor. More...
 
int PlaceText (const TOOL_EVENT &aEvent)
 Display a dialog that allows one to input text and its settings and then lets the user decide where to place the text in editor. More...
 
int DrawDimension (const TOOL_EVENT &aEvent)
 Start interactively drawing a dimension. More...
 
int DrawZone (const TOOL_EVENT &aEvent)
 Start interactively drawing a zone. More...
 
int DrawVia (const TOOL_EVENT &aEvent)
 
int PlaceImportedGraphics (const TOOL_EVENT &aEvent)
 Place a drawing imported from a DXF or SVG file in footprint editor. More...
 
int InteractivePlaceWithPreview (const TOOL_EVENT &aEvent, std::vector< BOARD_ITEM * > &aItems, std::vector< BOARD_ITEM * > &aPreview, LSET *aLayers)
 Interactively place a set of BOARD_ITEM. More...
 
int SetAnchor (const TOOL_EVENT &aEvent)
 Place the footprint anchor (only in footprint editor). More...
 
int ToggleHV45Mode (const TOOL_EVENT &toolEvent)
 Toggle the horizontal/vertical/45-degree constraint for drawing tools. More...
 
void setTransitions () override
 This method is meant to be overridden in order to specify handlers for events. More...
 
void SetStroke (const STROKE_PARAMS &aStroke, PCB_LAYER_ID aLayer)
 
void UpdateStatusBar () 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
 

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

bool drawShape (const TOOL_EVENT &aTool, PCB_SHAPE **aGraphic, std::optional< VECTOR2D > aStartingPoint)
 Start drawing a selected shape (i.e. More...
 
bool drawArc (const TOOL_EVENT &aTool, PCB_SHAPE **aGraphic, std::optional< VECTOR2D > aStartingPoint)
 Start drawing an arc. More...
 
bool getSourceZoneForAction (ZONE_MODE aMode, ZONE **aZone)
 Draw a polygon, that is added as a zone or a keepout area. More...
 
void constrainDimension (PCB_DIMENSION_BASE *aDim)
 Force the dimension lime to be drawn on multiple of 45 degrees. More...
 
VECTOR2I getClampedDifferenceEnd (const VECTOR2I &aOrigin, const VECTOR2I &aEnd)
 Clamps the end vector to respect numeric limits of difference representation. More...
 
VECTOR2I getClampedRadiusEnd (const VECTOR2I &aOrigin, const VECTOR2I &aEnd)
 Clamps the end vector to respect numeric limits of radius representation. More...
 
int getSegmentWidth (PCB_LAYER_ID aLayer) const
 
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

KIGFX::VIEWm_view
 
KIGFX::VIEW_CONTROLSm_controls
 
BOARDm_board
 
PCB_BASE_EDIT_FRAMEm_frame
 
MODE m_mode
 
bool m_inDrawingTool
 
PCB_LAYER_ID m_layer
 
STROKE_PARAMS m_stroke
 
TEXT_ATTRIBUTES m_textAttrs
 

Static Private Attributes

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

Friends

class ZONE_CREATE_HELPER
 

Detailed Description

Tool responsible for drawing graphical elements like lines, arcs, circles, etc.

Definition at line 50 of file drawing_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.

◆ MODE

enum class DRAWING_TOOL::MODE
strong
Enumerator
NONE 
LINE 
RECTANGLE 
CIRCLE 
ARC 
IMAGE 
TEXT 
ANCHOR 
DXF 
DIMENSION 
KEEPOUT 
ZONE 
GRAPHIC_POLYGON 
VIA 

Definition at line 63 of file drawing_tool.h.

64 {
65 NONE,
66 LINE,
68 CIRCLE,
69 ARC,
70 IMAGE,
71 TEXT,
72 ANCHOR,
73 DXF,
74 DIMENSION,
75 KEEPOUT,
76 ZONE,
78 VIA
79 };
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:33
Manage an 8-bit channel image.
Definition: image.h:90
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
@ NONE
Definition: kibis.h:53
@ VIA
Normal via.
Definition: router_tool.cpp:90

◆ 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

◆ DRAWING_TOOL()

DRAWING_TOOL::DRAWING_TOOL ( )

Definition at line 167 of file drawing_tool.cpp.

167 :
168 PCB_TOOL_BASE( "pcbnew.InteractiveDrawing" ),
169 m_view( nullptr ),
170 m_controls( nullptr ),
171 m_board( nullptr ),
172 m_frame( nullptr ),
174 m_inDrawingTool( false ),
176 m_stroke( 1, PLOT_DASH_TYPE::DEFAULT, COLOR4D::UNSPECIFIED )
177{
178}
PCB_LAYER_ID m_layer
Definition: drawing_tool.h:346
KIGFX::VIEW_CONTROLS * m_controls
Definition: drawing_tool.h:340
KIGFX::VIEW * m_view
Definition: drawing_tool.h:339
STROKE_PARAMS m_stroke
Definition: drawing_tool.h:347
bool m_inDrawingTool
Definition: drawing_tool.h:344
BOARD * m_board
Definition: drawing_tool.h:341
PCB_BASE_EDIT_FRAME * m_frame
Definition: drawing_tool.h:342
PCB_TOOL_BASE(TOOL_ID aId, const std::string &aName)
Constructor.
Definition: pcb_tool_base.h:77
@ UNDEFINED_LAYER
Definition: layer_ids.h:60

References DEFAULT, and UNSPECIFIED.

◆ ~DRAWING_TOOL()

DRAWING_TOOL::~DRAWING_TOOL ( )

Definition at line 181 of file drawing_tool.cpp.

182{
183}

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(), EDIT_TOOL::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(), EDIT_TOOL::doMoveSelection(), EDIT_TOOL::DragArcTrack(), DrawArc(), DrawCircle(), DrawDimension(), DrawLine(), MICROWAVE_TOOL::drawMicrowaveInductor(), DrawRectangle(), SCH_DRAWING_TOOLS::DrawShape(), SYMBOL_EDITOR_DRAWING_TOOLS::DrawShape(), PL_DRAWING_TOOLS::DrawShape(), SCH_DRAWING_TOOLS::DrawSheet(), DrawZone(), BOARD_EDITOR_CONTROL::DrillOrigin(), PAD_TOOL::EnumeratePads(), PCB_CONTROL::GridSetOrigin(), SCH_EDITOR_CONTROL::HighlightNetCursor(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), 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(), PlaceImage(), PlaceImportedGraphics(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), PlaceText(), EDIT_TOOL::Remove(), ROUTER_TOOL::RouteSelected(), POSITION_RELATIVE_TOOL::SelectPositionRelativeItem(), 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(), EDIT_TOOL::ChangeTrackWidth(), ZONE_FILLER_TOOL::CheckAllZones(), BOARD_INSPECTION_TOOL::ClearHighlight(), EDIT_TOOL::copyToClipboard(), FOOTPRINT_EDITOR_CONTROL::CreateFootprint(), MICROWAVE_TOOL::createInductorBetween(), ROUTER_TOOL::CustomTrackWidthDialog(), PCB_CONTROL::DeleteItemCursor(), PCB_TOOL_BASE::doInteractiveItemPlacement(), EDIT_TOOL::doMoveSelection(), EDIT_TOOL::DragArcTrack(), drawArc(), DrawDimension(), drawShape(), PAD_TOOL::EnumeratePads(), PAD_TOOL::explodePad(), BOARD_EDITOR_CONTROL::ExportNetlist(), ZONE_FILLER_TOOL::FillAllZones(), EDIT_TOOL::FilletTracks(), PCB_TOOL_BASE::footprint(), GROUP_TOOL::Group(), ROUTER_TOOL::handleLayerSwitch(), BOARD_INSPECTION_TOOL::highlightNet(), ROUTER_TOOL::Init(), ROUTER_TOOL::InlineDrag(), InteractivePlaceWithPreview(), PCB_CONTROL::LayerNext(), PCB_CONTROL::LayerPrev(), BOARD_INSPECTION_TOOL::LocalRatsnestTool(), EDIT_TOOL::MoveExact(), FOOTPRINT_EDITOR_CONTROL::NewFootprint(), PCB_CONTROL::Paste(), PCB_CONTROL::placeBoardItems(), BOARD_EDITOR_CONTROL::PlaceFootprint(), PAD_TOOL::PlacePad(), PlaceText(), PCB_CONTROL::pruneItemLayers(), EDIT_TOOL::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()

◆ constrainDimension()

void DRAWING_TOOL::constrainDimension ( PCB_DIMENSION_BASE aDim)
private

Force the dimension lime to be drawn on multiple of 45 degrees.

Parameters
aDimensionis the dimension element currently being drawn.

Definition at line 1044 of file drawing_tool.cpp.

1045{
1046 const VECTOR2I lineVector{ aDim->GetEnd() - aDim->GetStart() };
1047
1048 aDim->SetEnd( aDim->GetStart() + GetVectorSnapped45( lineVector ) );
1049 aDim->Update();
1050}
void Update()
Update the dimension's cached text and geometry.
virtual const VECTOR2I & GetStart() const
The dimension's origin is the first feature point for the dimension.
virtual void SetEnd(const VECTOR2I &aPoint)
virtual const VECTOR2I & GetEnd() const
VECTOR2< T > GetVectorSnapped45(const VECTOR2< T > &aVec, bool only45=false)
Snap a vector onto the nearest 0, 45 or 90 degree line.

References PCB_DIMENSION_BASE::GetEnd(), PCB_DIMENSION_BASE::GetStart(), GetVectorSnapped45(), PCB_DIMENSION_BASE::SetEnd(), and PCB_DIMENSION_BASE::Update().

Referenced by DrawDimension().

◆ controls()

◆ 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
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:70
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
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
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 selectionClear
Clear the current selection.
Definition: pcb_actions.h:59
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
BOARD * board() const
const PCB_SELECTION & selection() 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
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.
TOOL_MANAGER * GetManager() const
Return the instance of TOOL_MANAGER that takes care of the tool.
Definition: tool_base.h:144
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
Generic, UI-independent tool event.
Definition: tool_event.h:156
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
void Activate()
Run the tool.
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
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
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86

References TOOL_INTERACTIVE::Activate(), SELECTION::Add(), KIGFX::VIEW_GROUP::Add(), KIGFX::PCB_VIEW::Add(), ARROW, PCB_TOOL_BASE::board(), BUT_LEFT, BUT_RIGHT, KIGFX::VIEW_CONTROLS::CaptureCursor(), SELECTION::Clear(), 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(), DrawVia(), and PAD_TOOL::PlacePad().

◆ DrawArc()

int DRAWING_TOOL::DrawArc ( const TOOL_EVENT aEvent)

Start interactively drawing an arc.

After invoking the function it expects the user to first click on a point that is going to be used as the center of the arc. The second click determines the origin and radius, the third one - the angle.

Definition at line 484 of file drawing_tool.cpp.

485{
487 return 0;
488
489 if( m_inDrawingTool )
490 return 0;
491
493
494 FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
495 PCB_SHAPE* arc = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
496 BOARD_COMMIT commit( m_frame );
497 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::ARC );
498 std::optional<VECTOR2D> startingPoint;
499
500 arc->SetShape( SHAPE_T::ARC );
501 arc->SetFlags( IS_NEW );
502
503 m_frame->PushTool( aEvent );
504 Activate();
505
506 if( aEvent.HasPosition() )
507 startingPoint = aEvent.Position();
508
509 while( drawArc( aEvent, &arc, startingPoint ) )
510 {
511 if( arc )
512 {
514 static_cast<FP_SHAPE*>( arc )->SetLocalCoord();
515
516 commit.Add( arc );
517 commit.Push( _( "Draw an arc" ) );
518
520 }
521
522 arc = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
523 arc->SetShape( SHAPE_T::ARC );
524 arc->SetFlags( IS_NEW );
525
526 startingPoint = std::nullopt;
527 }
528
529 return 0;
530}
bool drawArc(const TOOL_EVENT &aTool, PCB_SHAPE **aGraphic, std::optional< VECTOR2D > aStartingPoint)
Start drawing an arc.
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:112
static TOOL_ACTION selectItem
Select an item (specified as the event parameter).
Definition: pcb_actions.h:62
bool m_isFootprintEditor
RAII class that sets an value at construction and resets it to the original value at destruction.
bool HasPosition() const
Definition: tool_event.h:243
const VECTOR2D Position() const
Returns the point where dragging has started.
Definition: tool_event.h:266
#define _(s)
#define IS_NEW
New item, just created.

References _, TOOL_INTERACTIVE::Activate(), COMMIT::Add(), ARC, ARC, drawArc(), PCB_BASE_FRAME::GetModel(), TOOL_EVENT::HasPosition(), IS_NEW, m_frame, m_inDrawingTool, PCB_TOOL_BASE::m_isFootprintEditor, m_mode, TOOL_BASE::m_toolMgr, TOOL_EVENT::Position(), BOARD_COMMIT::Push(), TOOLS_HOLDER::PushTool(), TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectItem, EDA_ITEM::SetFlags(), and EDA_SHAPE::SetShape().

Referenced by setTransitions().

◆ drawArc()

bool DRAWING_TOOL::drawArc ( const TOOL_EVENT aTool,
PCB_SHAPE **  aGraphic,
std::optional< VECTOR2D aStartingPoint 
)
private

Start drawing an arc.

Parameters
aGraphicis an object that is going to be used by the tool for drawing. Must be already created. The tool deletes the object if it is not added to a BOARD.
Returns
False if the tool was canceled before the origin was set or origin and end are the same point.

Definition at line 2196 of file drawing_tool.cpp.

2198{
2199 wxCHECK( aGraphic, false );
2200
2201 PCB_SHAPE*& graphic = *aGraphic;
2202
2203 wxCHECK( graphic, false );
2204
2205 if( m_layer != m_frame->GetActiveLayer() )
2206 {
2210 m_stroke.SetColor( COLOR4D::UNSPECIFIED );
2211 }
2212
2213 // Arc geometric construction manager
2215
2216 // Arc drawing assistant overlay
2218
2219 // Add a VIEW_GROUP that serves as a preview for the new item
2220 PCB_SELECTION preview;
2221 m_view->Add( &preview );
2222 m_view->Add( &arcAsst );
2224
2225 auto setCursor =
2226 [&]()
2227 {
2229 };
2230
2231 auto cleanup =
2232 [&] ()
2233 {
2234 preview.Clear();
2235 delete *aGraphic;
2236 *aGraphic = nullptr;
2237 };
2238
2239 m_controls->ShowCursor( true );
2241 // Set initial cursor
2242 setCursor();
2243
2244 bool started = false;
2245 bool cancelled = false;
2246
2248
2249 if( aStartingPoint )
2250 m_toolMgr->PrimeTool( *aStartingPoint );
2251
2252 // Main loop: keep receiving events
2253 while( TOOL_EVENT* evt = Wait() )
2254 {
2255 if( started )
2256 m_frame->SetMsgPanel( graphic );
2257
2258 setCursor();
2259
2260 graphic->SetLayer( m_layer );
2261
2262 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
2263 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
2264 VECTOR2I cursorPos = GetClampedCoords(
2265 grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic ), COORDS_PADDING );
2266 m_controls->ForceCursorPosition( true, cursorPos );
2267
2268 if( evt->IsCancelInteractive() )
2269 {
2270 cleanup();
2271
2272 if( !started )
2273 {
2274 // We've handled the cancel event. Don't cancel other tools
2275 evt->SetPassEvent( false );
2276 m_frame->PopTool( aTool );
2277 cancelled = true;
2278 }
2279
2280 break;
2281 }
2282 else if( evt->IsActivate() )
2283 {
2284 if( evt->IsPointEditor() )
2285 {
2286 // don't exit (the point editor runs in the background)
2287 }
2288 else if( evt->IsMoveTool() )
2289 {
2290 cleanup();
2291 // leave ourselves on the stack so we come back after the move
2292 cancelled = true;
2293 break;
2294 }
2295 else
2296 {
2297 cleanup();
2298 m_frame->PopTool( aTool );
2299 cancelled = true;
2300 break;
2301 }
2302 }
2303 else if( evt->IsClick( BUT_LEFT ) )
2304 {
2305 if( !started )
2306 {
2308
2309 m_controls->SetAutoPan( true );
2310 m_controls->CaptureCursor( true );
2311
2312 // Init the new item attributes
2313 // (non-geometric, those are handled by the manager)
2314 graphic->SetShape( SHAPE_T::ARC );
2315 graphic->SetStroke( m_stroke );
2316
2317 if( !m_view->IsLayerVisible( m_layer ) )
2318 {
2321 }
2322
2323 preview.Add( graphic );
2324 frame()->SetMsgPanel( graphic );
2325 started = true;
2326 }
2327
2328 arcManager.AddPoint( cursorPos, true );
2329 }
2330 else if( evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) )
2331 {
2332 arcManager.RemoveLastPoint();
2333 }
2334 else if( evt->IsMotion() )
2335 {
2336 // set angle snap
2337 arcManager.SetAngleSnap( Is45Limited() );
2338
2339 // update, but don't step the manager state
2340 arcManager.AddPoint( cursorPos, false );
2341 }
2342 else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
2343 {
2344 if( m_layer != m_frame->GetActiveLayer() )
2345 {
2349 m_stroke.SetColor( COLOR4D::UNSPECIFIED );
2350 }
2351
2352 if( graphic )
2353 {
2354 if( !m_view->IsLayerVisible( m_layer ) )
2355 {
2358 }
2359
2360 graphic->SetLayer( m_layer );
2361 graphic->SetStroke( m_stroke );
2362 m_view->Update( &preview );
2363 frame()->SetMsgPanel( graphic );
2364 }
2365 else
2366 {
2367 evt->SetPassEvent();
2368 }
2369 }
2370 else if( evt->IsAction( &PCB_ACTIONS::properties ) )
2371 {
2373 {
2374 graphic->SetArcAngleAndEnd( ANGLE_90 );
2375 frame()->OnEditItemRequest( graphic );
2376 m_view->Update( &preview );
2377 frame()->SetMsgPanel( graphic );
2378 break;
2379 }
2380 // Don't show the edit panel if we can't represent the arc with it
2381 else if( ( arcManager.GetStep() == KIGFX::PREVIEW::ARC_GEOM_MANAGER::SET_ANGLE )
2382 && ( arcManager.GetStartRadiusEnd() != arcManager.GetEndRadiusEnd() ) )
2383 {
2384 frame()->OnEditItemRequest( graphic );
2385 m_view->Update( &preview );
2386 frame()->SetMsgPanel( graphic );
2387 break;
2388 }
2389 else
2390 {
2391 evt->SetPassEvent();
2392 }
2393 }
2394 else if( evt->IsClick( BUT_RIGHT ) )
2395 {
2397 }
2398 else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
2399 {
2401 graphic->SetStroke( m_stroke );
2402 m_view->Update( &preview );
2403 frame()->SetMsgPanel( graphic );
2404 }
2405 else if( evt->IsAction( &PCB_ACTIONS::decWidth ) )
2406 {
2407 if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP )
2408 {
2410 graphic->SetStroke( m_stroke );
2411 m_view->Update( &preview );
2412 frame()->SetMsgPanel( graphic );
2413 }
2414 }
2415 else if( evt->IsAction( &PCB_ACTIONS::arcPosture ) )
2416 {
2417 arcManager.ToggleClockwise();
2418 }
2419 else if( evt->IsAction( &ACTIONS::updateUnits ) )
2420 {
2421 arcAsst.SetUnits( frame()->GetUserUnits() );
2422 m_view->Update( &arcAsst );
2423 evt->SetPassEvent();
2424 }
2425 else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
2426 {
2427 wxBell();
2428 }
2429 else
2430 {
2431 evt->SetPassEvent();
2432 }
2433
2434 if( arcManager.IsComplete() )
2435 {
2436 break;
2437 }
2438 else if( arcManager.HasGeometryChanged() )
2439 {
2440 updateArcFromConstructionMgr( arcManager, *graphic );
2441 m_view->Update( &preview );
2442 m_view->Update( &arcAsst );
2443
2444 if( started )
2445 frame()->SetMsgPanel( graphic );
2446 else
2447 frame()->SetMsgPanel( board() );
2448 }
2449 }
2450
2451 preview.Remove( graphic );
2452 m_view->Remove( &arcAsst );
2453 m_view->Remove( &preview );
2454
2455 if( selection().Empty() )
2457
2459 m_controls->SetAutoPan( false );
2460 m_controls->CaptureCursor( false );
2462
2463 return !cancelled;
2464}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
static TOOL_ACTION updateUnits
Definition: actions.h:151
void SetLayerVisible(int aLayer, bool isVisible)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:226
static const unsigned int WIDTH_STEP
Definition: drawing_tool.h:350
static const unsigned int COORDS_PADDING
Definition: drawing_tool.h:351
int getSegmentWidth(PCB_LAYER_ID aLayer) const
void SetMsgPanel(const std::vector< MSG_PANEL_ITEM > &aList)
Clear the message panel and populates it with the contents of aList.
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 SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
Definition: eda_shape.cpp:596
Represents an assistant draw when interactively drawing an arc on a canvas.
Definition: arc_assistant.h:39
Manage the construction of a circular arc though sequential setting of critical points: center,...
ARC_STEPS GetStep() const
Get the current step the manager is on (useful when drawing something depends on the current state)
void ToggleClockwise()
Set angle snapping (for the next point)
VECTOR2I GetStartRadiusEnd() const
Get the coordinates of the arc end point.
VECTOR2I GetEndRadiusEnd() const
Get the radius of the arc (valid if step >= SET_START)
@ SET_ANGLE
Waiting to lock in the arc end point.
@ SET_START
Waiting to lock in the arc start point.
void AddPoint(const VECTOR2I &aPt, bool aLockIn)
Add a point to the construction manager.
void RemoveLastPoint()
Undo the last point, and move the manager back to the previous step.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition: view.cpp:316
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition: view.cpp: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
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:410
static TOOL_ACTION deleteLastPoint
Definition: pcb_actions.h:193
static TOOL_ACTION layerChanged
Definition: pcb_actions.h:328
static TOOL_ACTION incWidth
Increase width of currently drawn line.
Definition: pcb_actions.h:197
static TOOL_ACTION decWidth
Decrease width of currently drawn line.
Definition: pcb_actions.h:200
static TOOL_ACTION arcPosture
Switch posture when drawing arc.
Definition: pcb_actions.h:203
APPEARANCE_CONTROLS * GetAppearancePanel()
virtual PCB_LAYER_ID GetActiveLayer() const
virtual MAGNETIC_SETTINGS * GetMagneticItemsSettings()
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:72
virtual bool Is45Limited() const
Should the tool use its 45° mode option?
virtual void Remove(EDA_ITEM *aItem)
Definition: selection.cpp:60
int GetWidth() const
Definition: stroke_params.h:98
void SetWidth(int aWidth)
Definition: stroke_params.h:99
void SetColor(const KIGFX::COLOR4D &aColor)
void SetPlotStyle(PLOT_DASH_TYPE aPlotStyle)
void PrimeTool(const VECTOR2D &aPosition)
"Prime" a tool by sending a cursor left-click event with the mouse position set to the passed in posi...
EDA_UNITS GetUserUnits() const
static bool IsZoneFillAction(const TOOL_EVENT *aEvent)
static void updateArcFromConstructionMgr(const KIGFX::PREVIEW::ARC_GEOM_MANAGER &aMgr, PCB_SHAPE &aArc)
Update an arc PCB_SHAPE from the current state of an Arc Geometry Manager.
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:431
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...
int GetUserUnits()
Return the currently selected user unit value for the interface.
@ MD_SHIFT
Definition: tool_event.h:138

References SELECTION::Add(), KIGFX::VIEW::Add(), KIGFX::PREVIEW::MULTISTEP_GEOM_MANAGER::AddPoint(), ANGLE_90, ARC, PCB_ACTIONS::arcPosture, ARROW, PCB_TOOL_BASE::board(), BUT_LEFT, BUT_RIGHT, KIGFX::VIEW_CONTROLS::CaptureCursor(), SELECTION::Clear(), COORDS_PADDING, PCB_ACTIONS::decWidth, DEFAULT, PCB_ACTIONS::deleteLastPoint, KIGFX::VIEW_CONTROLS::ForceCursorPosition(), PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetActiveLayer(), PCB_BASE_EDIT_FRAME::GetAppearancePanel(), PCB_BASE_FRAME::GetCanvas(), GetClampedCoords(), KIGFX::PREVIEW::ARC_GEOM_MANAGER::GetEndRadiusEnd(), PCB_BASE_FRAME::GetMagneticItemsSettings(), KIGFX::VIEW_CONTROLS::GetMousePosition(), getSegmentWidth(), KIGFX::PREVIEW::ARC_GEOM_MANAGER::GetStartRadiusEnd(), KIGFX::PREVIEW::ARC_GEOM_MANAGER::GetStep(), GetUserUnits(), UNITS_PROVIDER::GetUserUnits(), TOOL_BASE::getView(), STROKE_PARAMS::GetWidth(), grid, KIGFX::PREVIEW::MULTISTEP_GEOM_MANAGER::HasGeometryChanged(), PCB_ACTIONS::incWidth, PCB_TOOL_BASE::Is45Limited(), KIGFX::PREVIEW::MULTISTEP_GEOM_MANAGER::IsComplete(), KIGFX::VIEW::IsLayerVisible(), ZONE_FILLER_TOOL::IsZoneFillAction(), PCB_ACTIONS::layerChanged, m_controls, m_frame, m_layer, TOOL_INTERACTIVE::m_menu, m_stroke, TOOL_BASE::m_toolMgr, m_view, MD_SHIFT, PCB_BASE_EDIT_FRAME::OnEditItemRequest(), pcbIUScale, PENCIL, TOOLS_HOLDER::PopTool(), TOOL_MANAGER::PrimeTool(), PCB_ACTIONS::properties, EDA_DRAW_PANEL_GAL::Refresh(), ACTIONS::refreshPreview, SELECTION::Remove(), KIGFX::VIEW::Remove(), KIGFX::PREVIEW::MULTISTEP_GEOM_MANAGER::RemoveLastPoint(), TOOL_MANAGER::RunAction(), PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, KIGFX::PREVIEW::ARC_GEOM_MANAGER::SET_ANGLE, KIGFX::PREVIEW::ARC_GEOM_MANAGER::SET_START, KIGFX::PREVIEW::ARC_GEOM_MANAGER::SetAngleSnap(), EDA_SHAPE::SetArcAngleAndEnd(), KIGFX::VIEW_CONTROLS::SetAutoPan(), STROKE_PARAMS::SetColor(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), BOARD_ITEM::SetLayer(), APPEARANCE_CONTROLS::SetLayerVisible(), EDA_DRAW_FRAME::SetMsgPanel(), STROKE_PARAMS::SetPlotStyle(), EDA_SHAPE::SetShape(), PCB_SHAPE::SetStroke(), KIGFX::PREVIEW::ARC_ASSISTANT::SetUnits(), STROKE_PARAMS::SetWidth(), TOOL_MENU::ShowContextMenu(), KIGFX::VIEW_CONTROLS::ShowCursor(), KIGFX::PREVIEW::ARC_GEOM_MANAGER::ToggleClockwise(), KIGFX::VIEW::Update(), updateArcFromConstructionMgr(), ACTIONS::updateUnits, TOOL_INTERACTIVE::Wait(), and WIDTH_STEP.

Referenced by DrawArc().

◆ DrawBoardCharacteristics()

std::vector< BOARD_ITEM * > DRAWING_TOOL::DrawBoardCharacteristics ( const VECTOR2I origin,
PCB_LAYER_ID  aLayer,
bool  aDrawNow,
VECTOR2I tablesize 
)

Definition at line 360 of file drawing_stackup_table_tool.cpp.

364{
365 BOARD_COMMIT commit( m_frame );
366 std::vector<BOARD_ITEM*> objects;
368 BOARD_STACKUP& stackup = settings.GetStackupDescriptor();
369
370 VECTOR2I cursorPos = aOrigin;
371
372 // Style : Section header
373 std::unique_ptr<PCB_TEXT> headStyle =
374 std::make_unique<PCB_TEXT>( static_cast<FOOTPRINT*>( m_frame->GetModel() ) );
375 headStyle->SetLayer( Eco1_User );
376 headStyle->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 2.0 ), pcbIUScale.mmToIU( 2.0 ) ) );
377 headStyle->SetTextThickness( pcbIUScale.mmToIU( 0.4 ) );
378 headStyle->SetItalic( false );
379 headStyle->SetTextPos( VECTOR2I( 0, 0 ) );
380 headStyle->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
381 headStyle->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
382
383 // Style : Data
384 std::unique_ptr<PCB_TEXT> dataStyle =
385 std::make_unique<PCB_TEXT>( static_cast<FOOTPRINT*>( m_frame->GetModel() ) );
386 dataStyle->SetLayer( Eco1_User );
387 dataStyle->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 1.5 ), pcbIUScale.mmToIU( 1.5 ) ) );
388 dataStyle->SetTextThickness( pcbIUScale.mmToIU( 0.2 ) );
389 dataStyle->SetItalic( false );
390 dataStyle->SetTextPos( VECTOR2I( 0, 0 ) );
391 dataStyle->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
392 dataStyle->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
393
394 PCB_TEXT* t;
395
396 t = static_cast<PCB_TEXT*>( headStyle->Duplicate() );
397 t->SetText( _( "BOARD CHARACTERISTICS" ) );
398 t->SetPosition( cursorPos );
399 objects.push_back( t );
400
401 cursorPos.y = cursorPos.y + t->GetBoundingBox().GetHeight()
403
404 std::vector<std::vector<PCB_TEXT*>> texts;
405 std::vector<PCB_TEXT*> colLabel1;
406 std::vector<PCB_TEXT*> colData1;
407 std::vector<PCB_TEXT*> colbreak;
408 std::vector<PCB_TEXT*> colLabel2;
409 std::vector<PCB_TEXT*> colData2;
410
411 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
412 t->SetText( _( "Copper Layer Count: " ) );
413 colLabel1.push_back( t );
414
415 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
417 settings.GetCopperLayerCount(), false ) );
418 colData1.push_back( t );
419
420 SHAPE_POLY_SET outline;
422 BOX2I size = outline.BBox();
423 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
424 t->SetText( _( "Board overall dimensions: " ) );
425 colLabel1.push_back( t );
426
427 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
428 t->SetText( wxString::Format( wxT( "%s x %s" ),
429 m_frame->MessageTextFromValue( size.GetWidth(), true ),
430 m_frame->MessageTextFromValue( size.GetHeight(), true ) ) );
431 colData1.push_back( t );
432
433 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
434 t->SetText( _( "Min track/spacing: " ) );
435 colLabel1.push_back( t );
436
437 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
438 t->SetText( wxString::Format( wxT( "%s / %s" ),
440 m_frame->MessageTextFromValue( settings.m_MinClearance, true ) ) );
441 colData1.push_back( t );
442
443 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
444 t->SetText( _( "Copper Finish: " ) );
445 colLabel1.push_back( t );
446
447 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
448 t->SetText( stackup.m_FinishType );
449 colData1.push_back( t );
450
451 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
452 t->SetText( _( "Castellated pads: " ) );
453 colLabel1.push_back( t );
454
455 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
456 t->SetText( stackup.m_CastellatedPads ? _( "Yes" ) : _( "No" ) );
457 colData1.push_back( t );
458
459 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
460 t->SetText( _( "Board Thickness: " ) );
461 colLabel2.push_back( t );
462
463 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
464 t->SetText( m_frame->MessageTextFromValue( settings.GetBoardThickness(), true ) );
465 colData2.push_back( t );
466
467 // some empty cells
468 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
469 colLabel2.push_back( t );
470 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
471 colData2.push_back( t );
472
473 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
474 t->SetText( _( "Min hole diameter: " ) );
475 colLabel2.push_back( t );
476 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
477
478 double holeSize = std::min( settings.m_MinThroughDrill, settings.m_ViasMinSize );
479 t->SetText( m_frame->MessageTextFromValue( holeSize, true ) );
480 colData2.push_back( t );
481
482 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
483 t->SetText( _( "Impedance Control: " ) );
484 colLabel2.push_back( t );
485
486 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
487 t->SetText( stackup.m_HasDielectricConstrains ? _( "Yes" ) : _( "No" ) );
488 colData2.push_back( t );
489
490 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
491 t->SetText( _( "Plated Board Edge: " ) );
492 colLabel2.push_back( t );
493
494 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
495 t->SetText( stackup.m_EdgePlating ? _( "Yes" ) : _( "No" ) );
496 colData2.push_back( t );
497
498 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
499 t->SetText( _( "Edge card connectors: " ) );
500 colLabel1.push_back( t );
501
502 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
503 switch( stackup.m_EdgeConnectorConstraints )
504 {
505 case BS_EDGE_CONNECTOR_NONE: t->SetText( _( "No" ) ); break;
506 case BS_EDGE_CONNECTOR_IN_USE: t->SetText( _( "Yes" ) ); break;
507 case BS_EDGE_CONNECTOR_BEVELLED: t->SetText( _( "Yes, Bevelled" ) ); break;
508 }
509 colData1.push_back( t );
510
511 texts.push_back( colLabel1 );
512 texts.push_back( colData1 );
513 texts.push_back( colbreak );
514 texts.push_back( colLabel2 );
515 texts.push_back( colData2 );
516 VECTOR2I tableSize2;
517
518 std::vector<BOARD_ITEM*> table = initTextTable( texts, cursorPos, Eco1_User, &tableSize2,
519 false );
520
521 for( BOARD_ITEM* item : table )
522 objects.push_back( item );
523
524 if( aDrawNow )
525 {
526 for( BOARD_ITEM* item : objects )
527 commit.Add( item );
528
529 commit.Push( wxT( "Board Characteristics" ) );
530 }
531
532 tableSize->x = tableSize2.x;
533 tableSize->y = cursorPos.y + tableSize2.y
535
536 return objects;
537}
constexpr EDA_IU_SCALE unityScale
Definition: base_units.h:112
@ BS_EDGE_CONNECTOR_BEVELLED
Definition: board_stackup.h:57
@ BS_EDGE_CONNECTOR_NONE
Definition: board_stackup.h:55
@ BS_EDGE_CONNECTOR_IN_USE
Definition: board_stackup.h:56
Container for design settings for a BOARD object.
int GetBoardThickness() const
The full thickness of the board including copper and masks.
BOARD_STACKUP & GetStackupDescriptor()
Manage layers needed to make a physical board.
bool m_CastellatedPads
True if castellated pads exist.
bool m_HasDielectricConstrains
True if some layers have impedance controlled tracks or have specific constrains for micro-wave appli...
bool m_EdgePlating
True if the edge board is plated.
BS_EDGE_CONNECTOR_CONSTRAINTS m_EdgeConnectorConstraints
If the board has edge connector cards, some constrains can be specified in job file: BS_EDGE_CONNECTO...
wxString m_FinishType
The name of external copper finish.
bool GetBoardPolygonOutlines(SHAPE_POLY_SET &aOutlines, OUTLINE_ERROR_HANDLER *aErrorHandler=nullptr)
Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut l...
Definition: board.cpp:1972
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:704
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetWidth() const
Definition: box2.h:187
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:165
BOARD * GetBoard() const
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_text.cpp:140
virtual void SetPosition(const VECTOR2I &aPos) override
Definition: pcb_text.h:81
Represent a set of closed polygons.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A lower-precision version of StringFromValue().
static std::vector< BOARD_ITEM * > initTextTable(std::vector< std::vector< PCB_TEXT * > > aContent, VECTOR2I origin, PCB_LAYER_ID aLayer, VECTOR2I *aTableSize, bool aDrawFrame=true)
@ Eco1_User
Definition: layer_ids.h:111
double FromUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Return in internal units the value "val" given in a real unit such as "in", "mm" or "deg".
Definition: eda_units.cpp:385
wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Returns the string from aValue according to aUnits (inch, mm ...) for display.
Definition: eda_units.cpp:225
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
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_TOP
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590

References _, COMMIT::Add(), SHAPE_POLY_SET::BBox(), BS_EDGE_CONNECTOR_BEVELLED, BS_EDGE_CONNECTOR_IN_USE, BS_EDGE_CONNECTOR_NONE, Eco1_User, Format(), EDA_UNIT_UTILS::UI::FromUserUnit(), PCB_BASE_FRAME::GetBoard(), BOARD::GetBoardPolygonOutlines(), BOARD_DESIGN_SETTINGS::GetBoardThickness(), PCB_TEXT::GetBoundingBox(), BOARD_DESIGN_SETTINGS::GetCopperLayerCount(), BOARD::GetDesignSettings(), BOX2< Vec >::GetHeight(), PCB_BASE_FRAME::GetModel(), BOARD_DESIGN_SETTINGS::GetStackupDescriptor(), BOX2< Vec >::GetWidth(), GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_TOP, initTextTable(), BOARD_STACKUP::m_CastellatedPads, BOARD_STACKUP::m_EdgeConnectorConstraints, BOARD_STACKUP::m_EdgePlating, BOARD_STACKUP::m_FinishType, m_frame, BOARD_STACKUP::m_HasDielectricConstrains, BOARD_DESIGN_SETTINGS::m_MinClearance, BOARD_DESIGN_SETTINGS::m_MinThroughDrill, BOARD_DESIGN_SETTINGS::m_TrackMinWidth, BOARD_DESIGN_SETTINGS::m_ViasMinSize, UNITS_PROVIDER::MessageTextFromValue(), MILLIMETRES, EDA_IU_SCALE::mmToIU(), pcbIUScale, BOARD_COMMIT::Push(), PCB_TEXT::SetPosition(), EDA_TEXT::SetText(), EDA_UNIT_UTILS::UI::StringFromValue(), unityScale, UNSCALED, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by PlaceCharacteristics().

◆ DrawCircle()

int DRAWING_TOOL::DrawCircle ( const TOOL_EVENT aEvent)

Start interactively drawing a circle.

After invoking the function it expects the user to first click on a point that is going to be used as the center of the circle. The second click determines the circle radius.

Definition at line 433 of file drawing_tool.cpp.

434{
436 return 0;
437
438 if( m_inDrawingTool )
439 return 0;
440
442
443 FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
444 PCB_SHAPE* circle = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
445 BOARD_COMMIT commit( m_frame );
446 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::CIRCLE );
447 std::optional<VECTOR2D> startingPoint;
448
449 circle->SetShape( SHAPE_T::CIRCLE );
450 circle->SetFilled( false );
451 circle->SetFlags( IS_NEW );
452
453 if( aEvent.HasPosition() )
454 startingPoint = getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() );
455
456 m_frame->PushTool( aEvent );
457 Activate();
458
459 while( drawShape( aEvent, &circle, startingPoint ) )
460 {
461 if( circle )
462 {
464 static_cast<FP_SHAPE*>( circle )->SetLocalCoord();
465
466 commit.Add( circle );
467 commit.Push( _( "Draw a circle" ) );
468
470 }
471
472 circle = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
473 circle->SetShape( SHAPE_T::CIRCLE );
474 circle->SetFilled( false );
475 circle->SetFlags( IS_NEW );
476
477 startingPoint = std::nullopt;
478 }
479
480 return 0;
481}
bool drawShape(const TOOL_EVENT &aTool, PCB_SHAPE **aGraphic, std::optional< VECTOR2D > aStartingPoint)
Start drawing a selected shape (i.e.
void SetFilled(bool aFlag)
Definition: eda_shape.h:95
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
bool DisableGridSnapping() const
Definition: tool_event.h:344

References _, TOOL_INTERACTIVE::Activate(), COMMIT::Add(), CIRCLE, CIRCLE, TOOL_EVENT::DisableGridSnapping(), drawShape(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_BASE_FRAME::GetModel(), TOOL_BASE::getViewControls(), TOOL_EVENT::HasPosition(), IS_NEW, m_frame, m_inDrawingTool, PCB_TOOL_BASE::m_isFootprintEditor, m_mode, TOOL_BASE::m_toolMgr, BOARD_COMMIT::Push(), TOOLS_HOLDER::PushTool(), TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectItem, EDA_SHAPE::SetFilled(), EDA_ITEM::SetFlags(), and EDA_SHAPE::SetShape().

Referenced by setTransitions().

◆ DrawDimension()

int DRAWING_TOOL::DrawDimension ( const TOOL_EVENT aEvent)

Start interactively drawing a dimension.

After invoking the function it expects the user to first click on a point that is going to be used as the origin of the dimension. The second click determines the end and the third click modifies its height.

Definition at line 1053 of file drawing_tool.cpp.

1054{
1056 return 0;
1057
1058 if( m_inDrawingTool )
1059 return 0;
1060
1062
1063 enum DIMENSION_STEPS
1064 {
1065 SET_ORIGIN = 0,
1066 SET_END,
1067 SET_HEIGHT,
1068 FINISHED
1069 };
1070
1071 TOOL_EVENT originalEvent = aEvent;
1072 PCB_DIMENSION_BASE* dimension = nullptr;
1073 BOARD_COMMIT commit( m_frame );
1076 PCB_SELECTION preview; // A VIEW_GROUP that serves as a preview for the new item(s)
1077 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DIMENSION );
1078 int step = SET_ORIGIN;
1080
1081 m_view->Add( &preview );
1082
1083 auto cleanup =
1084 [&]()
1085 {
1086 m_controls->SetAutoPan( false );
1087 m_controls->CaptureCursor( false );
1089
1090 preview.Clear();
1091 m_view->Update( &preview );
1092
1093 delete dimension;
1094 dimension = nullptr;
1095 step = SET_ORIGIN;
1096 };
1097
1098 auto setCursor =
1099 [&]()
1100 {
1102 };
1103
1105
1106 m_frame->PushTool( aEvent );
1107
1108 Activate();
1109 // Must be done after Activate() so that it gets set into the correct context
1110 m_controls->ShowCursor( true );
1112 // Set initial cursor
1113 setCursor();
1114
1116
1117 if( aEvent.HasPosition() )
1118 m_toolMgr->PrimeTool( aEvent.Position() );
1119
1120 // Main loop: keep receiving events
1121 while( TOOL_EVENT* evt = Wait() )
1122 {
1123 if( step > SET_ORIGIN )
1124 frame()->SetMsgPanel( dimension );
1125
1126 setCursor();
1127
1128 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1129 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
1130
1131 if( step == SET_HEIGHT )
1132 {
1133 if( dimension->GetStart().x != dimension->GetEnd().x
1134 && dimension->GetStart().y != dimension->GetEnd().y )
1135 {
1136 // Not cardinal. Grid snapping doesn't make sense for height.
1137 grid.SetUseGrid( false );
1138 }
1139 }
1140
1141 VECTOR2I cursorPos = evt->HasPosition() ? evt->Position() : m_controls->GetMousePosition();
1142 cursorPos = GetClampedCoords( grid.BestSnapAnchor( cursorPos, nullptr ), COORDS_PADDING );
1143
1144 m_controls->ForceCursorPosition( true, cursorPos );
1145
1146 if( evt->IsCancelInteractive() )
1147 {
1148 m_controls->SetAutoPan( false );
1149
1150 if( step != SET_ORIGIN ) // start from the beginning
1151 {
1152 cleanup();
1153 }
1154 else
1155 {
1156 m_frame->PopTool( aEvent );
1157 break;
1158 }
1159 }
1160 else if( evt->IsActivate() )
1161 {
1162 if( step != SET_ORIGIN )
1163 cleanup();
1164
1165 if( evt->IsPointEditor() )
1166 {
1167 // don't exit (the point editor runs in the background)
1168 }
1169 else if( evt->IsMoveTool() )
1170 {
1171 // leave ourselves on the stack so we come back after the move
1172 break;
1173 }
1174 else
1175 {
1176 m_frame->PopTool( aEvent );
1177 break;
1178 }
1179 }
1180 else if( evt->IsAction( &PCB_ACTIONS::incWidth ) && step != SET_ORIGIN )
1181 {
1183 dimension->SetLineThickness( m_stroke.GetWidth() );
1184 m_view->Update( &preview );
1185 frame()->SetMsgPanel( dimension );
1186 }
1187 else if( evt->IsAction( &PCB_ACTIONS::decWidth ) && step != SET_ORIGIN )
1188 {
1189 if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP )
1190 {
1192 dimension->SetLineThickness( m_stroke.GetWidth() );
1193 m_view->Update( &preview );
1194 frame()->SetMsgPanel( dimension );
1195 }
1196 }
1197 else if( evt->IsClick( BUT_RIGHT ) )
1198 {
1200 }
1201 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
1202 {
1203 switch( step )
1204 {
1205 case SET_ORIGIN:
1206 {
1208
1210
1211 // Init the new item attributes
1212 auto setMeasurementAttributes =
1213 [&]( PCB_DIMENSION_BASE* aDim )
1214 {
1215 aDim->SetUnitsMode( boardSettings.m_DimensionUnitsMode );
1216 aDim->SetUnitsFormat( boardSettings.m_DimensionUnitsFormat );
1217 aDim->SetPrecision( boardSettings.m_DimensionPrecision );
1218 aDim->SetSuppressZeroes( boardSettings.m_DimensionSuppressZeroes );
1219 aDim->SetTextPositionMode( boardSettings.m_DimensionTextPosition );
1220 aDim->SetKeepTextAligned( boardSettings.m_DimensionKeepTextAligned );
1221 };
1222
1223 if( originalEvent.IsAction( &PCB_ACTIONS::drawAlignedDimension ) )
1224 {
1225 dimension = new PCB_DIM_ALIGNED( m_frame->GetModel(),
1228 setMeasurementAttributes( dimension );
1229 }
1230 else if( originalEvent.IsAction( &PCB_ACTIONS::drawOrthogonalDimension ) )
1231 {
1233 setMeasurementAttributes( dimension );
1234 }
1235 else if( originalEvent.IsAction( &PCB_ACTIONS::drawCenterDimension ) )
1236 {
1237 dimension = new PCB_DIM_CENTER( m_frame->GetModel(), m_isFootprintEditor );
1238 }
1239 else if( originalEvent.IsAction( &PCB_ACTIONS::drawRadialDimension ) )
1240 {
1241 dimension = new PCB_DIM_RADIAL( m_frame->GetModel(), m_isFootprintEditor );
1242 setMeasurementAttributes( dimension );
1243 }
1244 else if( originalEvent.IsAction( &PCB_ACTIONS::drawLeader ) )
1245 {
1246 dimension = new PCB_DIM_LEADER( m_frame->GetModel(), m_isFootprintEditor );
1247 dimension->SetTextPos( cursorPos );
1248 }
1249 else
1250 {
1251 wxFAIL_MSG( wxT( "Unhandled action in DRAWING_TOOL::DrawDimension" ) );
1252 }
1253
1254 t = dimension->Type();
1255
1256 dimension->SetLayer( layer );
1257 dimension->SetTextSize( boardSettings.GetTextSize( layer ) );
1258 dimension->SetTextThickness( boardSettings.GetTextThickness( layer ) );
1259 dimension->SetItalic( boardSettings.GetTextItalic( layer ) );
1260 dimension->SetLineThickness( boardSettings.GetLineThickness( layer ) );
1261 dimension->SetArrowLength( boardSettings.m_DimensionArrowLength );
1262 dimension->SetExtensionOffset( boardSettings.m_DimensionExtensionOffset );
1263 dimension->SetStart( cursorPos );
1264 dimension->SetEnd( cursorPos );
1265 dimension->Update();
1266
1267 if( !m_view->IsLayerVisible( layer ) )
1268 {
1269 m_frame->GetAppearancePanel()->SetLayerVisible( layer, true );
1271 }
1272
1273 preview.Add( dimension );
1274 frame()->SetMsgPanel( dimension );
1275
1276 m_controls->SetAutoPan( true );
1277 m_controls->CaptureCursor( true );
1278 break;
1279 }
1280
1281 case SET_END:
1282 // Dimensions that have origin and end in the same spot are not valid
1283 if( dimension->GetStart() == dimension->GetEnd() )
1284 {
1285 --step;
1286 break;
1287 }
1288
1289 if( t == PCB_DIM_CENTER_T || t == PCB_DIM_RADIAL_T || t == PCB_DIM_LEADER_T
1291 {
1292 // No separate height step
1293 ++step;
1295 }
1296 else
1297 {
1298 break;
1299 }
1300
1301 case SET_HEIGHT:
1302 assert( dimension->GetStart() != dimension->GetEnd() );
1303 assert( dimension->GetLineThickness() > 0 );
1304
1305 preview.Remove( dimension );
1306
1307 commit.Add( dimension );
1308 commit.Push( _( "Draw a dimension" ) );
1309
1310 if( t == PCB_DIM_LEADER_T || t == PCB_FP_DIM_LEADER_T )
1311 {
1312 // Run the edit immediately to set the leader text
1313 m_toolMgr->RunAction( PCB_ACTIONS::properties, true, dimension );
1314 }
1315
1316 m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, dimension );
1317
1318 break;
1319 }
1320
1321 if( ++step >= FINISHED )
1322 {
1323 dimension = nullptr;
1324 step = SET_ORIGIN;
1325 m_controls->SetAutoPan( false );
1326 m_controls->CaptureCursor( false );
1327 }
1328 else if( evt->IsDblClick( BUT_LEFT ) )
1329 {
1331 }
1332 }
1333 else if( evt->IsMotion() )
1334 {
1335 switch( step )
1336 {
1337 case SET_END:
1338 dimension->SetEnd( cursorPos );
1339
1340 if( Is45Limited() || t == PCB_DIM_CENTER_T || t == PCB_FP_DIM_CENTER_T )
1341 constrainDimension( dimension );
1342
1344 {
1345 PCB_DIM_ORTHOGONAL* ortho = static_cast<PCB_DIM_ORTHOGONAL*>( dimension );
1346
1347 BOX2I bounds( dimension->GetStart(),
1348 dimension->GetEnd() - dimension->GetStart() );
1349
1350 // Create a nice preview by measuring the longer dimension
1351 bool vert = bounds.GetWidth() < bounds.GetHeight();
1352
1353 ortho->SetOrientation( vert ? PCB_DIM_ORTHOGONAL::DIR::VERTICAL
1355 }
1356 else if( t == PCB_DIM_RADIAL_T || t == PCB_FP_DIM_RADIAL_T )
1357 {
1358 PCB_DIM_RADIAL* radialDim = static_cast<PCB_DIM_RADIAL*>( dimension );
1359 VECTOR2I textOffset( radialDim->GetArrowLength() * 10, 0 );
1360
1361 if( radialDim->GetEnd().x < radialDim->GetStart().x )
1362 textOffset = -textOffset;
1363
1364 radialDim->SetTextPos( radialDim->GetKnee() + textOffset );
1365 }
1366 else if( t == PCB_DIM_LEADER_T || t == PCB_FP_DIM_LEADER_T )
1367 {
1368 VECTOR2I textOffset( dimension->GetArrowLength() * 10, 0 );
1369
1370 if( dimension->GetEnd().x < dimension->GetStart().x )
1371 textOffset = -textOffset;
1372
1373 dimension->SetTextPos( dimension->GetEnd() + textOffset );
1374 }
1375
1376 dimension->Update();
1377 break;
1378
1379 case SET_HEIGHT:
1380 if( t == PCB_DIM_ALIGNED_T || t == PCB_FP_DIM_ALIGNED_T )
1381 {
1382 PCB_DIM_ALIGNED* aligned = static_cast<PCB_DIM_ALIGNED*>( dimension );
1383
1384 // Calculating the direction of travel perpendicular to the selected axis
1385 double angle = aligned->GetAngle() + ( M_PI / 2 );
1386
1387 VECTOR2I delta( (VECTOR2I) cursorPos - dimension->GetEnd() );
1388 double height = ( delta.x * cos( angle ) ) + ( delta.y * sin( angle ) );
1389 aligned->SetHeight( height );
1390 aligned->Update();
1391 }
1392 else if( t == PCB_DIM_ORTHOGONAL_T || t == PCB_FP_DIM_ORTHOGONAL_T )
1393 {
1394 PCB_DIM_ORTHOGONAL* ortho = static_cast<PCB_DIM_ORTHOGONAL*>( dimension );
1395
1396 BOX2I bbox( dimension->GetStart(),
1397 dimension->GetEnd() - dimension->GetStart() );
1398 VECTOR2I direction( cursorPos - bbox.Centre() );
1399 bool vert;
1400
1401 // Only change the orientation when we move outside the bbox
1402 if( !bbox.Contains( cursorPos ) )
1403 {
1404 // If the dimension is horizontal or vertical, set correct orientation
1405 // otherwise, test if we're left/right of the bounding box or above/below it
1406 if( bbox.GetWidth() == 0 )
1407 vert = true;
1408 else if( bbox.GetHeight() == 0 )
1409 vert = false;
1410 else if( cursorPos.x > bbox.GetLeft() && cursorPos.x < bbox.GetRight() )
1411 vert = false;
1412 else if( cursorPos.y > bbox.GetTop() && cursorPos.y < bbox.GetBottom() )
1413 vert = true;
1414 else
1415 vert = std::abs( direction.y ) < std::abs( direction.x );
1416
1417 ortho->SetOrientation( vert ? PCB_DIM_ORTHOGONAL::DIR::VERTICAL
1419 }
1420 else
1421 {
1422 vert = ortho->GetOrientation() == PCB_DIM_ORTHOGONAL::DIR::VERTICAL;
1423 }
1424
1425 VECTOR2I heightVector( cursorPos - dimension->GetStart() );
1426 ortho->SetHeight( vert ? heightVector.x : heightVector.y );
1427 ortho->Update();
1428 }
1429
1430 break;
1431 }
1432
1433 // Show a preview of the item
1434 m_view->Update( &preview );
1435 }
1436 else if( dimension && evt->IsAction( &PCB_ACTIONS::layerChanged ) )
1437 {
1439
1440 if( !m_view->IsLayerVisible( layer ) )
1441 {
1442 m_frame->GetAppearancePanel()->SetLayerVisible( layer, true );
1444 }
1445
1446 dimension->SetLayer( layer );
1447 dimension->SetTextSize( boardSettings.GetTextSize( layer ) );
1448 dimension->SetTextThickness( boardSettings.GetTextThickness( layer ) );
1449 dimension->SetItalic( boardSettings.GetTextItalic( layer ) );
1450 dimension->SetLineThickness( boardSettings.GetLineThickness( layer ) );
1451 dimension->Update();
1452
1453 m_view->Update( &preview );
1454 frame()->SetMsgPanel( dimension );
1455 }
1456 else if( dimension && evt->IsAction( &PCB_ACTIONS::properties ) )
1457 {
1458 if( step == SET_END || step == SET_HEIGHT )
1459 {
1460 frame()->OnEditItemRequest( dimension );
1461 dimension->Update();
1462 frame()->SetMsgPanel( dimension );
1463 break;
1464 }
1465 else
1466 {
1467 wxBell();
1468 }
1469 }
1470 else if( dimension && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
1471 {
1472 wxBell();
1473 }
1474 else
1475 {
1476 evt->SetPassEvent();
1477 }
1478 }
1479
1480 if( step != SET_ORIGIN )
1481 delete dimension;
1482
1483 m_controls->SetAutoPan( false );
1485 m_controls->CaptureCursor( false );
1487
1488 m_view->Remove( &preview );
1489
1490 if( selection().Empty() )
1492
1493 return 0;
1494}
static TOOL_ACTION cursorClick
Definition: actions.h:127
DIM_PRECISION m_DimensionPrecision
Number of digits after the decimal.
DIM_UNITS_FORMAT m_DimensionUnitsFormat
int GetTextThickness(PCB_LAYER_ID aLayer) const
Return the default text thickness from the layer class for the given layer.
bool GetTextItalic(PCB_LAYER_ID aLayer) const
VECTOR2I GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
DIM_TEXT_POSITION m_DimensionTextPosition
DIM_UNITS_MODE m_DimensionUnitsMode
void constrainDimension(PCB_DIMENSION_BASE *aDim)
Force the dimension lime to be drawn on multiple of 45 degrees.
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:373
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:187
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:349
void SetItalic(bool aItalic)
Definition: eda_text.cpp:203
static TOOL_ACTION drawOrthogonalDimension
Definition: pcb_actions.h:181
static TOOL_ACTION drawRadialDimension
Definition: pcb_actions.h:180
static TOOL_ACTION drawLeader
Definition: pcb_actions.h:182
static TOOL_ACTION drawCenterDimension
Definition: pcb_actions.h:179
static TOOL_ACTION drawAlignedDimension
Definition: pcb_actions.h:178
Abstract dimension API.
int GetLineThickness() const
void SetExtensionOffset(int aOffset)
void SetLineThickness(int aWidth)
void SetArrowLength(int aLength)
virtual void SetStart(const VECTOR2I &aPoint)
int GetArrowLength() const
For better understanding of the points that make a dimension:
double GetAngle() const
Return the angle of the crossbar.
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
Mark the center of a circle or arc with a cross shape.
A leader is a dimension-like object pointing to a specific point.
An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the X or ...
A radial dimension indicates either the radius or diameter of an arc or circle.
VECTOR2I GetKnee() const
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
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418
constexpr int delta
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_FP_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:95
@ 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_FP_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:97
@ PCB_FP_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition: typeinfo.h:99
@ PCB_FP_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:96
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition: typeinfo.h:106
@ PCB_FP_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:98
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:105
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition: typeinfo.h:109

References _, std::abs(), TOOL_INTERACTIVE::Activate(), COMMIT::Add(), SELECTION::Add(), KIGFX::VIEW::Add(), PNS::angle(), ARROW, PCB_TOOL_BASE::board(), BUT_LEFT, BUT_RIGHT, KIGFX::VIEW_CONTROLS::CaptureCursor(), BOX2< Vec >::Centre(), SELECTION::Clear(), constrainDimension(), BOX2< Vec >::Contains(), COORDS_PADDING, ACTIONS::cursorClick, PCB_ACTIONS::decWidth, delta, DIMENSION, PCB_ACTIONS::drawAlignedDimension, PCB_ACTIONS::drawCenterDimension, PCB_ACTIONS::drawLeader, PCB_ACTIONS::drawOrthogonalDimension, PCB_ACTIONS::drawRadialDimension, KIGFX::VIEW_CONTROLS::ForceCursorPosition(), PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetActiveLayer(), PCB_DIM_ALIGNED::GetAngle(), PCB_BASE_EDIT_FRAME::GetAppearancePanel(), PCB_DIMENSION_BASE::GetArrowLength(), BOX2< Vec >::GetBottom(), PCB_BASE_FRAME::GetCanvas(), GetClampedCoords(), BOARD::GetDesignSettings(), PCB_DIMENSION_BASE::GetEnd(), BOX2< Vec >::GetHeight(), PCB_DIM_RADIAL::GetKnee(), BOX2< Vec >::GetLeft(), PCB_DIMENSION_BASE::GetLineThickness(), BOARD_DESIGN_SETTINGS::GetLineThickness(), PCB_BASE_FRAME::GetMagneticItemsSettings(), PCB_BASE_FRAME::GetModel(), KIGFX::VIEW_CONTROLS::GetMousePosition(), BOX2< Vec >::GetRight(), PCB_DIMENSION_BASE::GetStart(), BOARD_DESIGN_SETTINGS::GetTextItalic(), BOARD_DESIGN_SETTINGS::GetTextSize(), BOARD_DESIGN_SETTINGS::GetTextThickness(), BOX2< Vec >::GetTop(), TOOL_BASE::getView(), STROKE_PARAMS::GetWidth(), BOX2< Vec >::GetWidth(), grid, TOOL_EVENT::HasPosition(), PCB_DIM_ORTHOGONAL::HORIZONTAL, PCB_ACTIONS::incWidth, PCB_TOOL_BASE::Is45Limited(), TOOL_EVENT::IsAction(), KIGFX::VIEW::IsLayerVisible(), ZONE_FILLER_TOOL::IsZoneFillAction(), KI_FALLTHROUGH, PCB_ACTIONS::layerChanged, m_board, m_controls, BOARD_DESIGN_SETTINGS::m_DimensionArrowLength, BOARD_DESIGN_SETTINGS::m_DimensionExtensionOffset, BOARD_DESIGN_SETTINGS::m_DimensionKeepTextAligned, BOARD_DESIGN_SETTINGS::m_DimensionPrecision, BOARD_DESIGN_SETTINGS::m_DimensionSuppressZeroes, BOARD_DESIGN_SETTINGS::m_DimensionTextPosition, BOARD_DESIGN_SETTINGS::m_DimensionUnitsFormat, BOARD_DESIGN_SETTINGS::m_DimensionUnitsMode, m_frame, m_inDrawingTool, PCB_TOOL_BASE::m_isFootprintEditor, TOOL_INTERACTIVE::m_menu, m_mode, m_stroke, TOOL_BASE::m_toolMgr, m_view, MD_SHIFT, MEASURE, PCB_BASE_EDIT_FRAME::OnEditItemRequest(), ortho, PCB_DIM_ALIGNED_T, PCB_DIM_CENTER_T, PCB_DIM_LEADER_T, PCB_DIM_ORTHOGONAL_T, PCB_DIM_RADIAL_T, PCB_DIMENSION_T, PCB_FP_DIM_ALIGNED_T, PCB_FP_DIM_CENTER_T, PCB_FP_DIM_LEADER_T, PCB_FP_DIM_ORTHOGONAL_T, PCB_FP_DIM_RADIAL_T, TOOLS_HOLDER::PopTool(), TOOL_EVENT::Position(), TOOL_MANAGER::PrimeTool(), PCB_ACTIONS::properties, BOARD_COMMIT::Push(), TOOLS_HOLDER::PushTool(), EDA_DRAW_PANEL_GAL::Refresh(), ACTIONS::refreshPreview, SELECTION::Remove(), KIGFX::VIEW::Remove(), TOOL_MANAGER::RunAction(), PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItem, PCB_DIMENSION_BASE::SetArrowLength(), KIGFX::VIEW_CONTROLS::SetAutoPan(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), PCB_DIMENSION_BASE::SetEnd(), PCB_DIMENSION_BASE::SetExtensionOffset(), PCB_DIM_ALIGNED::SetHeight(), EDA_TEXT::SetItalic(), BOARD_ITEM::SetLayer(), APPEARANCE_CONTROLS::SetLayerVisible(), PCB_DIMENSION_BASE::SetLineThickness(), EDA_DRAW_FRAME::SetMsgPanel(), PCB_DIMENSION_BASE::SetStart(), EDA_TEXT::SetTextPos(), EDA_TEXT::SetTextSize(), EDA_TEXT::SetTextThickness(), STROKE_PARAMS::SetWidth(), TOOL_MENU::ShowContextMenu(), KIGFX::VIEW_CONTROLS::ShowCursor(), EDA_ITEM::Type(), PCB_DIMENSION_BASE::Update(), KIGFX::VIEW::Update(), PCB_DIM_ORTHOGONAL::VERTICAL, TOOL_INTERACTIVE::Wait(), WIDTH_STEP, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by setTransitions().

◆ DrawLine()

int DRAWING_TOOL::DrawLine ( const TOOL_EVENT aEvent)

Start interactively drawing a line.

After invoking the function it expects the user to click at least two times to determine the origin and the end for a line. If there are more clicks, the line is drawn as a continuous polyline.

Definition at line 302 of file drawing_tool.cpp.

303{
305 return 0;
306
307 if( m_inDrawingTool )
308 return 0;
309
311
312 FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
313 PCB_SHAPE* line = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
314 BOARD_COMMIT commit( m_frame );
315 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::LINE );
316 std::optional<VECTOR2D> startingPoint;
317
318 line->SetShape( SHAPE_T::SEGMENT );
319 line->SetFlags( IS_NEW );
320
321 if( aEvent.HasPosition() )
322 startingPoint = getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() );
323
324 m_frame->PushTool( aEvent );
325 Activate();
326
327 while( drawShape( aEvent, &line, startingPoint ) )
328 {
329 if( line )
330 {
332 static_cast<FP_SHAPE*>( line )->SetLocalCoord();
333
334 commit.Add( line );
335 commit.Push( _( "Draw a line segment" ) );
336 startingPoint = VECTOR2D( line->GetEnd() );
337 }
338 else
339 {
340 startingPoint = std::nullopt;
341 }
342
343 line = m_isFootprintEditor ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
344 line->SetShape( SHAPE_T::SEGMENT );
345 line->SetFlags( IS_NEW );
346 }
347
348 return 0;
349}
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:145
VECTOR2< double > VECTOR2D
Definition: vector2d.h:589

References _, TOOL_INTERACTIVE::Activate(), COMMIT::Add(), TOOL_EVENT::DisableGridSnapping(), drawShape(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), EDA_SHAPE::GetEnd(), PCB_BASE_FRAME::GetModel(), TOOL_BASE::getViewControls(), TOOL_EVENT::HasPosition(), IS_NEW, LINE, m_frame, m_inDrawingTool, PCB_TOOL_BASE::m_isFootprintEditor, m_mode, BOARD_COMMIT::Push(), TOOLS_HOLDER::PushTool(), SEGMENT, EDA_ITEM::SetFlags(), and EDA_SHAPE::SetShape().

Referenced by setTransitions().

◆ DrawRectangle()

int DRAWING_TOOL::DrawRectangle ( const TOOL_EVENT aEvent)

Start interactively drawing a rectangle.

After invoking the function it expects the user to first click on a point that is going to be used as the top-left of the rectangle. The second click determines the bottom-right.

Definition at line 352 of file drawing_tool.cpp.

353{
355 return 0;
356
357 if( m_inDrawingTool )
358 return 0;
359
361
362 bool isTextBox = aEvent.IsAction( &PCB_ACTIONS::drawTextBox );
363 PCB_SHAPE* rect = nullptr;
364 BOARD_COMMIT commit( m_frame );
365 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::RECTANGLE );
366 std::optional<VECTOR2D> startingPoint;
367
368 auto makeNew =
369 [&]() -> PCB_SHAPE*
370 {
372 {
373 FOOTPRINT* parentFootprint = dynamic_cast<FOOTPRINT*>( m_frame->GetModel() );
374
375 if( isTextBox )
376 return new FP_TEXTBOX( parentFootprint );
377 else
378 return new FP_SHAPE( parentFootprint );
379 }
380 else
381 {
382 if( isTextBox )
383 return new PCB_TEXTBOX( m_frame->GetModel() );
384 else
385 return new PCB_SHAPE();
386 }
387 };
388
389 rect = makeNew();
390 rect->SetShape( SHAPE_T::RECT );
391 rect->SetFilled( false );
392 rect->SetFlags( IS_NEW );
393
394 if( aEvent.HasPosition() )
395 startingPoint = getViewControls()->GetCursorPosition( !aEvent.DisableGridSnapping() );
396
397 m_frame->PushTool( aEvent );
398 Activate();
399
400 while( drawShape( aEvent, &rect, startingPoint ) )
401 {
402 if( rect )
403 {
405 static_cast<FP_SHAPE*>( rect )->SetLocalCoord();
406
407 if( isTextBox && m_frame->ShowTextBoxPropertiesDialog( rect ) != wxID_OK )
408 {
409 delete rect;
410 rect = nullptr;
411 }
412 else
413 {
414 rect->NormalizeRect();
415 commit.Add( rect );
416 commit.Push( isTextBox ? _( "Draw a text box" ) : _( "Draw a rectangle" ) );
417
419 }
420 }
421
422 rect = makeNew();
423 rect->SetShape( SHAPE_T::RECT );
424 rect->SetFilled( false );
425 rect->SetFlags( IS_NEW );
426 startingPoint = std::nullopt;
427 }
428
429 return 0;
430}
static TOOL_ACTION drawTextBox
Definition: pcb_actions.h:177
int ShowTextBoxPropertiesDialog(BOARD_ITEM *aText)
void NormalizeRect()
Definition: pcb_shape.cpp:175

References _, TOOL_INTERACTIVE::Activate(), COMMIT::Add(), TOOL_EVENT::DisableGridSnapping(), drawShape(), PCB_ACTIONS::drawTextBox, KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_BASE_FRAME::GetModel(), TOOL_BASE::getViewControls(), TOOL_EVENT::HasPosition(), IS_NEW, TOOL_EVENT::IsAction(), m_frame, m_inDrawingTool, PCB_TOOL_BASE::m_isFootprintEditor, m_mode, TOOL_BASE::m_toolMgr, PCB_SHAPE::NormalizeRect(), BOARD_COMMIT::Push(), TOOLS_HOLDER::PushTool(), RECT, RECTANGLE, TOOL_MANAGER::RunAction(), PCB_ACTIONS::selectItem, EDA_SHAPE::SetFilled(), EDA_ITEM::SetFlags(), EDA_SHAPE::SetShape(), and PCB_BASE_EDIT_FRAME::ShowTextBoxPropertiesDialog().

Referenced by setTransitions().

◆ drawShape()

bool DRAWING_TOOL::drawShape ( const TOOL_EVENT aTool,
PCB_SHAPE **  aGraphic,
std::optional< VECTOR2D aStartingPoint 
)
private

Start drawing a selected shape (i.e.

PCB_SHAPE).

Parameters
aGraphicis an object that is going to be used by the tool for drawing. Must be already created. The tool deletes the object if it is not added to a BOARD.
aStartingPointis a starting point for this new PCB_SHAPE. If it exists the new item has its start point set to aStartingPoint, and its settings (width, layer) set to the current default values.
Returns
False if the tool was canceled before the origin was set or origin and end are the same point.

Definition at line 1799 of file drawing_tool.cpp.

1801{
1802 SHAPE_T shape = ( *aGraphic )->GetShape();
1803
1804 // Only three shapes are currently supported
1805 wxASSERT( shape == SHAPE_T::SEGMENT || shape == SHAPE_T::CIRCLE || shape == SHAPE_T::RECT );
1806
1808 EDA_UNITS userUnits = m_frame->GetUserUnits();
1810 PCB_SHAPE*& graphic = *aGraphic;
1811
1812 if( m_layer != m_frame->GetActiveLayer() )
1813 {
1817 m_stroke.SetColor( COLOR4D::UNSPECIFIED );
1818
1827 }
1828
1829 // geometric construction manager
1831
1832 // drawing assistant overlay
1833 // TODO: workaround because EDA_SHAPE_TYPE_T is not visible from commons.
1834 KIGFX::PREVIEW::GEOM_SHAPE geomShape( static_cast<KIGFX::PREVIEW::GEOM_SHAPE>( shape ) );
1835 KIGFX::PREVIEW::TWO_POINT_ASSISTANT twoPointAsst( twoPointManager, pcbIUScale, userUnits, geomShape );
1836
1837 // Add a VIEW_GROUP that serves as a preview for the new item
1838 PCB_SELECTION preview;
1839 m_view->Add( &preview );
1840 m_view->Add( &twoPointAsst );
1841
1842 bool started = false;
1843 bool cancelled = false;
1844 bool isLocalOriginSet = ( m_frame->GetScreen()->m_LocalOrigin != VECTOR2D( 0, 0 ) );
1845 VECTOR2I cursorPos = m_controls->GetMousePosition();
1846
1847 auto setCursor =
1848 [&]()
1849 {
1851 };
1852
1853 auto cleanup =
1854 [&]()
1855 {
1856 preview.Clear();
1857 m_view->Update( &preview );
1858 delete graphic;
1859 graphic = nullptr;
1860
1861 if( !isLocalOriginSet )
1863 };
1864
1865 m_controls->ShowCursor( true );
1867 // Set initial cursor
1868 setCursor();
1869
1871
1872 if( aStartingPoint )
1873 m_toolMgr->PrimeTool( *aStartingPoint );
1874
1875 // Main loop: keep receiving events
1876 while( TOOL_EVENT* evt = Wait() )
1877 {
1878 setCursor();
1879
1880 if( started )
1881 m_frame->SetMsgPanel( graphic );
1882
1883 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
1884 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
1885 cursorPos = GetClampedCoords(
1886 grid.BestSnapAnchor( m_controls->GetMousePosition(), m_layer ),
1888 m_controls->ForceCursorPosition( true, cursorPos );
1889
1890 if( evt->IsCancelInteractive() )
1891 {
1892 cleanup();
1893
1894 if( !started )
1895 {
1896 // We've handled the cancel event. Don't cancel other tools
1897 evt->SetPassEvent( false );
1898 m_frame->PopTool( aTool );
1899 cancelled = true;
1900 }
1901
1902 break;
1903 }
1904 else if( evt->IsActivate() )
1905 {
1906 if( evt->IsPointEditor() )
1907 {
1908 // don't exit (the point editor runs in the background)
1909 }
1910 else if( evt->IsMoveTool() )
1911 {
1912 cleanup();
1913 // leave ourselves on the stack so we come back after the move
1914 cancelled = true;
1915 break;
1916 }
1917 else
1918 {
1919 cleanup();
1920 m_frame->PopTool( aTool );
1921 cancelled = true;
1922 break;
1923 }
1924 }
1925 else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
1926 {
1927 if( m_layer != m_frame->GetActiveLayer() )
1928 {
1932 m_stroke.SetColor( COLOR4D::UNSPECIFIED );
1933
1942 }
1943
1944 if( graphic )
1945 {
1946 if( !m_view->IsLayerVisible( m_layer ) )
1947 {
1950 }
1951
1952 graphic->SetLayer( m_layer );
1953 graphic->SetStroke( m_stroke );
1954
1955 if( FP_TEXTBOX* fp_textbox = dynamic_cast<FP_TEXTBOX*>( graphic ) )
1956 fp_textbox->SetAttributes( m_textAttrs );
1957 else if( PCB_TEXTBOX* pcb_textbox = dynamic_cast<PCB_TEXTBOX*>( graphic ) )
1958 pcb_textbox->SetAttributes( m_textAttrs );
1959
1960 m_view->Update( &preview );
1961 frame()->SetMsgPanel( graphic );
1962 }
1963 else
1964 {
1965 evt->SetPassEvent();
1966 }
1967 }
1968 else if( evt->IsClick( BUT_RIGHT ) )
1969 {
1971 }
1972 else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) )
1973 {
1974 if( !graphic )
1975 break;
1976
1977 if( !started )
1978 {
1980
1981 if( aStartingPoint )
1982 {
1983 cursorPos = *aStartingPoint;
1984 aStartingPoint = std::nullopt;
1985 }
1986
1987 // Init the new item attributes
1988 if( graphic ) // always true, but Coverity can't seem to figure that out
1989 {
1990 graphic->SetShape( static_cast<SHAPE_T>( shape ) );
1991 graphic->SetFilled( false );
1992 graphic->SetStroke( m_stroke );
1993 graphic->SetLayer( m_layer );
1994 }
1995
1996 if( FP_TEXTBOX* fp_textbox = dynamic_cast<FP_TEXTBOX*>( graphic ) )
1997 fp_textbox->SetAttributes( m_textAttrs );
1998 else if( PCB_TEXTBOX* pcb_textbox = dynamic_cast<PCB_TEXTBOX*>( graphic ) )
1999 pcb_textbox->SetAttributes( m_textAttrs );
2000
2001 grid.SetSkipPoint( cursorPos );
2002
2003 twoPointManager.SetOrigin( cursorPos );
2004 twoPointManager.SetEnd( cursorPos );
2005
2006 if( !isLocalOriginSet )
2007 m_frame->GetScreen()->m_LocalOrigin = cursorPos;
2008
2009 preview.Add( graphic );
2010 frame()->SetMsgPanel( graphic );
2011 m_controls->SetAutoPan( true );
2012 m_controls->CaptureCursor( true );
2013
2014 if( !m_view->IsLayerVisible( m_layer ) )
2015 {
2018 }
2019
2020 updateSegmentFromGeometryMgr( twoPointManager, graphic );
2021
2022 started = true;
2023 }
2024 else if( shape == SHAPE_T::CIRCLE )
2025 {
2026 // No clever logic if drawing a circle
2027 preview.Clear();
2028 twoPointManager.Reset();
2029 break;
2030 }
2031 else
2032 {
2033 PCB_SHAPE* snapItem = dyn_cast<PCB_SHAPE*>( grid.GetSnapped() );
2034
2035 if( twoPointManager.GetOrigin() == twoPointManager.GetEnd()
2036 || ( evt->IsDblClick( BUT_LEFT ) && shape == SHAPE_T::SEGMENT )
2037 || snapItem )
2038 // User has clicked twice in the same spot
2039 // or clicked on the end of an existing segment (closing a path)
2040 {
2041 BOARD_COMMIT commit( m_frame );
2042
2043 // If the user clicks on an existing snap point from a drawsegment
2044 // we finish the segment as they are likely closing a path
2045 if( snapItem && ( shape == SHAPE_T::RECT || graphic->GetLength() > 0.0 ) )
2046 {
2047 commit.Add( graphic );
2048 commit.Push( _( "Draw a line segment" ) );
2049 m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, graphic );
2050 }
2051 else
2052 {
2053 delete graphic;
2054 }
2055
2056 graphic = nullptr;
2057 }
2058
2059 preview.Clear();
2060 twoPointManager.Reset();
2061 break;
2062 }
2063
2064 twoPointManager.SetEnd( GetClampedCoords( cursorPos ) );
2065 }
2066 else if( evt->IsMotion() )
2067 {
2068 VECTOR2I clampedCursorPos = cursorPos;
2069
2070 if( shape == SHAPE_T::CIRCLE || shape == SHAPE_T::ARC )
2071 {
2072 clampedCursorPos = getClampedRadiusEnd( twoPointManager.GetOrigin(), cursorPos );
2073 }
2074 else
2075 {
2076 clampedCursorPos = getClampedDifferenceEnd( twoPointManager.GetOrigin(),
2077 cursorPos );
2078 }
2079
2080 // 45 degree lines
2081 if( started && Is45Limited() )
2082 {
2083 const VECTOR2I lineVector( clampedCursorPos
2084 - VECTOR2I( twoPointManager.GetOrigin() ) );
2085
2086 // get a restricted 45/H/V line from the last fixed point to the cursor
2087 VECTOR2I newEnd = GetVectorSnapped45( lineVector, ( shape == SHAPE_T::RECT ) );
2088 m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
2089 twoPointManager.SetEnd( twoPointManager.GetOrigin() + newEnd );
2090 twoPointManager.SetAngleSnap( true );
2091 }
2092 else
2093 {
2094 twoPointManager.SetEnd( clampedCursorPos );
2095 twoPointManager.SetAngleSnap( false );
2096 }
2097
2098 updateSegmentFromGeometryMgr( twoPointManager, graphic );
2099 m_view->Update( &preview );
2100 m_view->Update( &twoPointAsst );
2101 }
2102 else if( graphic && evt->IsAction( &PCB_ACTIONS::incWidth ) )
2103 {
2105 graphic->SetStroke( m_stroke );
2106 m_view->Update( &preview );
2107 frame()->SetMsgPanel( graphic );
2108 }
2109 else if( graphic && evt->IsAction( &PCB_ACTIONS::decWidth ) )
2110 {
2111 if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP )
2112 {
2114 graphic->SetStroke( m_stroke );
2115 m_view->Update( &preview );
2116 frame()->SetMsgPanel( graphic );
2117 }
2118 }
2119 else if( started && evt->IsAction( &PCB_ACTIONS::properties ) )
2120 {
2121 frame()->OnEditItemRequest( graphic );
2122 m_view->Update( &preview );
2123 frame()->SetMsgPanel( graphic );
2124 break;
2125 }
2126 else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
2127 {
2128 wxBell();
2129 }
2130 else if( evt->IsAction( &ACTIONS::resetLocalCoords ) )
2131 {
2132 isLocalOriginSet = true;
2133 evt->SetPassEvent();
2134 }
2135 else if( evt->IsAction( &ACTIONS::updateUnits ) )
2136 {
2137 if( frame()->GetUserUnits() != userUnits )
2138 {
2139 userUnits = frame()->GetUserUnits();
2140 twoPointAsst.SetUnits( userUnits );
2141 m_view->Update( &twoPointAsst );
2142 }
2143 evt->SetPassEvent();
2144 }
2145 else
2146 {
2147 evt->SetPassEvent();
2148 }
2149 }
2150
2151 if( !isLocalOriginSet ) // reset the relative coordinate if it was not set before
2153
2154 m_view->Remove( &twoPointAsst );
2155 m_view->Remove( &preview );
2156
2157 if( selection().Empty() )
2159
2161 m_controls->SetAutoPan( false );
2162 m_controls->CaptureCursor( false );
2164
2165 return !cancelled;
2166}
static TOOL_ACTION resetLocalCoords
Definition: actions.h:154
VECTOR2D m_LocalOrigin
Relative Screen cursor coordinate (on grid) in user units.
Definition: base_screen.h:90
bool GetTextUpright(PCB_LAYER_ID aLayer) const
TEXT_ATTRIBUTES m_textAttrs
Definition: drawing_tool.h:348
VECTOR2I getClampedDifferenceEnd(const VECTOR2I &aOrigin, const VECTOR2I &aEnd)
Clamps the end vector to respect numeric limits of difference representation.
Definition: drawing_tool.h:284
VECTOR2I getClampedRadiusEnd(const VECTOR2I &aOrigin, const VECTOR2I &aEnd)
Clamps the end vector to respect numeric limits of radius representation.
Definition: drawing_tool.h:314
double GetLength() const
Return the length of the track using the hypotenuse calculation.
Definition: eda_shape.cpp:110
Represents an assistant draw when interactively drawing a line or circle on a canvas.
Represent a very simple geometry manager for items that have a start and end point.
void SetOrigin(const VECTOR2I &aOrigin)
< Set the origin of the ruler (the fixed end)
void Reset()
Reset the manager to the initial state.
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
PCB_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Returns the BOARD_DESIGN_SETTINGS for the open project.
bool m_KeepUpright
If true, keep rotation angle between -90...90 degrees for readability.
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
static void updateSegmentFromGeometryMgr(const KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER &aMgr, PCB_SHAPE *aGraphic)
Update a PCB_SHAPE from the current state of a #TWO_POINT_GEOMETRY_MANAGER.
SHAPE_T
Definition: eda_shape.h:41
EDA_UNITS
Definition: eda_units.h:43
void InferBold(TEXT_ATTRIBUTES *aAttrs)
Definition: gr_text.h:88
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition: layer_ids.h:924

References _, COMMIT::Add(), SELECTION::Add(), KIGFX::VIEW::Add(), ARC, ARROW, PCB_TOOL_BASE::board(), BUT_LEFT, BUT_RIGHT, KIGFX::VIEW_CONTROLS::CaptureCursor(), CIRCLE, SELECTION::Clear(), COORDS_PADDING, PCB_ACTIONS::decWidth, DEFAULT, KIGFX::VIEW_CONTROLS::ForceCursorPosition(), PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetActiveLayer(), PCB_BASE_EDIT_FRAME::GetAppearancePanel(), PCB_BASE_FRAME::GetCanvas(), GetClampedCoords(), getClampedDifferenceEnd(), getClampedRadiusEnd(), PCB_BASE_FRAME::GetDesignSettings(), KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER::GetEnd(), EDA_SHAPE::GetLength(), PCB_BASE_FRAME::GetMagneticItemsSettings(), KIGFX::VIEW_CONTROLS::GetMousePosition(), KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER::GetOrigin(), PCB_BASE_FRAME::GetScreen(), getSegmentWidth(), BOARD_DESIGN_SETTINGS::GetTextItalic(), BOARD_DESIGN_SETTINGS::GetTextSize(), BOARD_DESIGN_SETTINGS::GetTextThickness(), BOARD_DESIGN_SETTINGS::GetTextUpright(), GetUserUnits(), UNITS_PROVIDER::GetUserUnits(), GetVectorSnapped45(), TOOL_BASE::getView(), STROKE_PARAMS::GetWidth(), GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_TOP, grid, PCB_ACTIONS::incWidth, InferBold(), PCB_TOOL_BASE::Is45Limited(), IsBackLayer(), KIGFX::VIEW::IsLayerVisible(), ZONE_FILLER_TOOL::IsZoneFillAction(), PCB_ACTIONS::layerChanged, m_controls, m_frame, TEXT_ATTRIBUTES::m_Halign, TEXT_ATTRIBUTES::m_Italic, TEXT_ATTRIBUTES::m_KeepUpright, m_layer, BASE_SCREEN::m_LocalOrigin, TOOL_INTERACTIVE::m_menu, TEXT_ATTRIBUTES::m_Mirrored, TEXT_ATTRIBUTES::m_Size, m_stroke, TEXT_ATTRIBUTES::m_StrokeWidth, m_textAttrs, TOOL_BASE::m_toolMgr, TEXT_ATTRIBUTES::m_Valign, m_view, MD_SHIFT, PCB_BASE_EDIT_FRAME::OnEditItemRequest(), pcbIUScale, PENCIL, TOOLS_HOLDER::PopTool(), TOOL_MANAGER::PrimeTool(), PCB_ACTIONS::properties, BOARD_COMMIT::Push(), RECT, EDA_DRAW_PANEL_GAL::Refresh(), ACTIONS::refreshPreview, KIGFX::VIEW::Remove(), KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER::Reset(), ACTIONS::resetLocalCoords, TOOL_MANAGER::RunAction(), SEGMENT, PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectItem, KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER::SetAngleSnap(), KIGFX::VIEW_CONTROLS::SetAutoPan(), STROKE_PARAMS::SetColor(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER::SetEnd(), EDA_SHAPE::SetFilled(), BOARD_ITEM::SetLayer(), APPEARANCE_CONTROLS::SetLayerVisible(), EDA_DRAW_FRAME::SetMsgPanel(), KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER::SetOrigin(), STROKE_PARAMS::SetPlotStyle(), EDA_SHAPE::SetShape(), PCB_SHAPE::SetStroke(), KIGFX::PREVIEW::TWO_POINT_ASSISTANT::SetUnits(), STROKE_PARAMS::SetWidth(), TOOL_MENU::ShowContextMenu(), KIGFX::VIEW_CONTROLS::ShowCursor(), KIGFX::VIEW::Update(), updateSegmentFromGeometryMgr(), ACTIONS::updateUnits, TOOL_INTERACTIVE::Wait(), and WIDTH_STEP.

Referenced by DrawCircle(), DrawLine(), and DrawRectangle().

◆ DrawSpecificationStackup()

std::vector< BOARD_ITEM * > DRAWING_TOOL::DrawSpecificationStackup ( const VECTOR2I origin,
PCB_LAYER_ID  aLayer,
bool  aDrawNow,
VECTOR2I tablesize 
)

Definition at line 196 of file drawing_stackup_table_tool.cpp.

200{
201 BOARD_COMMIT commit( m_frame );
202 FOOTPRINT* footprint = static_cast<FOOTPRINT*>( m_frame->GetModel() );
203
204 std::vector<std::vector<PCB_TEXT*>> texts;
205
206 // Style : Header
207 std::unique_ptr<PCB_TEXT> headStyle = std::make_unique<PCB_TEXT>( footprint );
208 headStyle->SetLayer( Eco1_User );
209 headStyle->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 1.5 ), pcbIUScale.mmToIU( 1.5 ) ) );
210 headStyle->SetTextThickness( pcbIUScale.mmToIU( 0.3 ) );
211 headStyle->SetItalic( false );
212 headStyle->SetTextPos( VECTOR2I( 0, 0 ) );
213 headStyle->SetText( _( "Layer" ) );
214 headStyle->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
215 headStyle->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
216
217 // Style : data
218 std::unique_ptr<PCB_TEXT> dataStyle = std::make_unique<PCB_TEXT>( footprint );
219 dataStyle->SetLayer( Eco1_User );
220 dataStyle->SetTextSize( VECTOR2I( pcbIUScale.mmToIU( 1.5 ), pcbIUScale.mmToIU( 1.5 ) ) );
221 dataStyle->SetTextThickness( pcbIUScale.mmToIU( 0.1 ) );
222 dataStyle->SetItalic( false );
223 dataStyle->SetTextPos( VECTOR2I( 0, 0 ) );
224 dataStyle->SetText( _( "Layer" ) );
225 dataStyle->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
226 dataStyle->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
227
228 //Get Layer names
230 BOARD_STACKUP& stackup = dsnSettings.GetStackupDescriptor();
231 stackup.SynchronizeWithBoard( &dsnSettings );
232
233 std::vector<BOARD_STACKUP_ITEM*> layers = stackup.GetList();
234
235 std::vector<PCB_TEXT*> colLayer;
236 std::vector<PCB_TEXT*> colType;
237 std::vector<PCB_TEXT*> colMaterial;
238 std::vector<PCB_TEXT*> colThickness;
239 std::vector<PCB_TEXT*> colColor;
240 std::vector<PCB_TEXT*> colEpsilon;
241 std::vector<PCB_TEXT*> colTanD;
242 PCB_TEXT* t;
243
244 t = static_cast<PCB_TEXT*>( headStyle->Duplicate() );
245 t->SetText( _( "Layer Name" ) );
246 colLayer.push_back( t );
247
248 t = static_cast<PCB_TEXT*>( headStyle->Duplicate() );
249 t->SetText( _( "Type" ) );
250 colType.push_back( t );
251
252 t = static_cast<PCB_TEXT*>( headStyle->Duplicate() );
253 t->SetText( _( "Material" ) );
254 colMaterial.push_back( t );
255
256 t = static_cast<PCB_TEXT*>( headStyle->Duplicate() );
257
258 switch( m_frame->GetUserUnits() )
259 {
260 case EDA_UNITS::MILLIMETRES: t->SetText( _( "Thickness (mm)" ) ); break;
261 case EDA_UNITS::INCHES: t->SetText( _( "Thickness (inches)" ) ); break;
262 case EDA_UNITS::MILS: t->SetText( _( "Thickness (mils)" ) ); break;
263 default: wxFAIL_MSG( wxT( "Unhandled unit type" ) );
264 }
265
266 colThickness.push_back( t );
267
268 t = static_cast<PCB_TEXT*>( headStyle->Duplicate() );
269 t->SetText( _( "Color" ) );
270 colColor.push_back( t );
271
272 t = static_cast<PCB_TEXT*>( headStyle->Duplicate() );
273 t->SetText( _( "Epsilon R" ) );
274 colEpsilon.push_back( t );
275
276 t = static_cast<PCB_TEXT*>( headStyle->Duplicate() );
277 t->SetText( _( "Loss Tangent" ) );
278 colTanD.push_back( t );
279
280 for( int i = 0; i < stackup.GetCount(); i++ )
281 {
282 BOARD_STACKUP_ITEM* stackup_item = layers.at( i );
283
284 for( int sublayer_id = 0; sublayer_id < stackup_item->GetSublayersCount(); sublayer_id++ )
285 {
286 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
287
288 // Layer names are empty until we close at least once the board setup dialog.
289 // If the user did not open the dialog, then get the names from the board.
290 // But dielectric layer names will be missing.
291 // In this case, for dielectric, a dummy name will be used
292 if( stackup_item->GetLayerName().IsEmpty() )
293 {
294 wxString ly_name;
295
296 if( IsValidLayer( stackup_item->GetBrdLayerId() ) )
297 ly_name = m_frame->GetBoard()->GetLayerName( stackup_item->GetBrdLayerId() );
298
299 if( ly_name.IsEmpty() && stackup_item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
300 ly_name = _( "Dielectric" );
301
302 t->SetText( ly_name );
303 }
304 else
305 {
306 t->SetText( stackup_item->GetLayerName() );
307 }
308
309 colLayer.push_back( t );
310
311 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
312 t->SetText( stackup_item->GetTypeName() );
313 colType.push_back( t );
314
315 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
316 t->SetText( stackup_item->GetMaterial( sublayer_id ) );
317 colMaterial.push_back( t );
318
319 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
320 t->SetText( m_frame->StringFromValue( stackup_item->GetThickness( sublayer_id ), true ) );
321 colThickness.push_back( t );
322
323 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
324 t->SetText( stackup_item->GetColor( sublayer_id ) );
325 colColor.push_back( t );
326
327 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
329 stackup_item->GetEpsilonR( sublayer_id ), false ) );
330 colEpsilon.push_back( t );
331
332 t = static_cast<PCB_TEXT*>( dataStyle->Duplicate() );
334 stackup_item->GetLossTangent( sublayer_id ), false ) );
335 colTanD.push_back( t );
336 }
337 }
338
339 texts.push_back( colLayer );
340 texts.push_back( colType );
341 texts.push_back( colMaterial );
342 texts.push_back( colThickness );
343 texts.push_back( colColor );
344 texts.push_back( colEpsilon );
345 texts.push_back( colTanD );
346 std::vector<BOARD_ITEM*> table = initTextTable( texts, aOrigin, aLayer, tableSize, true );
347
348 if( aDrawNow )
349 {
350 for( BOARD_ITEM* item : table )
351 commit.Add( item );
352
353 commit.Push( _( "Insert board stackup table" ) );
354 }
355
356 return table;
357}
@ BS_ITEM_TYPE_DIELECTRIC
Definition: board_stackup.h:44
Manage one layer needed to make a physical board.
Definition: board_stackup.h:91
wxString GetTypeName() const
int GetSublayersCount() const
double GetEpsilonR(int aDielectricSubLayer=0) const
wxString GetColor(int aDielectricSubLayer=0) const
wxString GetLayerName() const
PCB_LAYER_ID GetBrdLayerId() const
int GetThickness(int aDielectricSubLayer=0) const
BOARD_STACKUP_ITEM_TYPE GetType() const
wxString GetMaterial(int aDielectricSubLayer=0) const
double GetLossTangent(int aDielectricSubLayer=0) const
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
int GetCount() const
bool SynchronizeWithBoard(BOARD_DESIGN_SETTINGS *aSettings)
Synchronize the BOARD_STACKUP_ITEM* list with the board.
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:474
FOOTPRINT * footprint() const
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Converts aValue in internal units into a united string.
bool IsValidLayer(int aLayerId)
Test whether a given integer is a valid layer index, i.e.
Definition: layer_ids.h:805

References _, COMMIT::Add(), BS_ITEM_TYPE_DIELECTRIC, Eco1_User, PCB_TOOL_BASE::footprint(), PCB_BASE_FRAME::GetBoard(), BOARD_STACKUP_ITEM::GetBrdLayerId(), BOARD_STACKUP_ITEM::GetColor(), BOARD_STACKUP::GetCount(), PCB_BASE_FRAME::GetDesignSettings(), BOARD_STACKUP_ITEM::GetEpsilonR(), BOARD_STACKUP_ITEM::GetLayerName(), BOARD::GetLayerName(), BOARD_STACKUP::GetList(), BOARD_STACKUP_ITEM::GetLossTangent(), BOARD_STACKUP_ITEM::GetMaterial(), PCB_BASE_FRAME::GetModel(), BOARD_DESIGN_SETTINGS::GetStackupDescriptor(), BOARD_STACKUP_ITEM::GetSublayersCount(), BOARD_STACKUP_ITEM::GetThickness(), BOARD_STACKUP_ITEM::GetType(), BOARD_STACKUP_ITEM::GetTypeName(), UNITS_PROVIDER::GetUserUnits(), GR_TEXT_H_ALIGN_LEFT, GR_TEXT_V_ALIGN_TOP, INCHES, initTextTable(), IsValidLayer(), m_frame, MILLIMETRES, MILS, EDA_IU_SCALE::mmToIU(), pcbIUScale, BOARD_COMMIT::Push(), EDA_TEXT::SetText(), EDA_UNIT_UTILS::UI::StringFromValue(), UNITS_PROVIDER::StringFromValue(), BOARD_STACKUP::SynchronizeWithBoard(), unityScale, and UNSCALED.

Referenced by PlaceStackup().

◆ DrawVia()

int DRAWING_TOOL::DrawVia ( const TOOL_EVENT aEvent)

Definition at line 2730 of file drawing_tool.cpp.

2731{
2733 return 0;
2734
2735 struct VIA_PLACER : public INTERACTIVE_PLACER_BASE
2736 {
2738 PCB_GRID_HELPER m_gridHelper;
2739 std::shared_ptr<DRC_ENGINE> m_drcEngine;
2740 int m_drcEpsilon;
2741 int m_worstClearance;
2742 bool m_allowDRCViolations;
2743
2744 VIA_PLACER( PCB_BASE_EDIT_FRAME* aFrame ) :
2745 m_frame( aFrame ),
2746 m_gridHelper( aFrame->GetToolManager(), aFrame->GetMagneticItemsSettings() ),
2747 m_drcEngine( aFrame->GetBoard()->GetDesignSettings().m_DRCEngine ),
2748 m_drcEpsilon( aFrame->GetBoard()->GetDesignSettings().GetDRCEpsilon() ),
2749 m_worstClearance( 0 )
2750 {
2752
2753 m_allowDRCViolations = router->Router()->Settings().AllowDRCViolations();
2754
2755 try
2756 {
2757 m_drcEngine->InitEngine( aFrame->GetDesignRulesPath() );
2758
2759 DRC_CONSTRAINT constraint;
2760
2761 if( m_drcEngine->QueryWorstConstraint( CLEARANCE_CONSTRAINT, constraint ) )
2762 m_worstClearance = constraint.GetValue().Min();
2763
2764 if( m_drcEngine->QueryWorstConstraint( HOLE_CLEARANCE_CONSTRAINT, constraint ) )
2765 m_worstClearance = std::max( m_worstClearance, constraint.GetValue().Min() );
2766
2767 for( FOOTPRINT* footprint : aFrame->GetBoard()->Footprints() )
2768 {
2769 for( PAD* pad : footprint->Pads() )
2770 m_worstClearance = std::max( m_worstClearance, pad->GetLocalClearance() );
2771 }
2772 }
2773 catch( PARSE_ERROR& )
2774 {
2775 }
2776 }
2777
2778 virtual ~VIA_PLACER()
2779 {
2780 }
2781
2782 PCB_TRACK* findTrack( PCB_VIA* aVia )
2783 {
2784 const LSET lset = aVia->GetLayerSet();
2785 VECTOR2I position = aVia->GetPosition();
2786 BOX2I bbox = aVia->GetBoundingBox();
2787
2788 std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> items;
2790 std::vector<PCB_TRACK*> possible_tracks;
2791
2792 view->Query( bbox, items );
2793
2794 for( const KIGFX::VIEW::LAYER_ITEM_PAIR& it : items )
2795 {
2796 BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it.first );
2797
2798 if( !( item->GetLayerSet() & lset ).any() )
2799 continue;
2800
2801 if( PCB_TRACK* track = dyn_cast<PCB_TRACK*>( item ) )
2802 {
2803 if( TestSegmentHit( position, track->GetStart(), track->GetEnd(),
2804 ( track->GetWidth() + aVia->GetWidth() ) / 2 ) )
2805 {
2806 possible_tracks.push_back( track );
2807 }
2808 }
2809 }
2810
2811 PCB_TRACK* return_track = nullptr;
2812 int min_d = std::numeric_limits<int>::max();
2813
2814 for( PCB_TRACK* track : possible_tracks )
2815 {
2816 SEG test( track->GetStart(), track->GetEnd() );
2817 int dist = ( test.NearestPoint( position ) - position ).EuclideanNorm();
2818
2819 if( dist < min_d )
2820 {
2821 min_d = dist;
2822 return_track = track;
2823 }
2824 }
2825
2826 return return_track;
2827 }
2828
2829 bool hasDRCViolation( PCB_VIA* aVia, BOARD_ITEM* aOther )
2830 {
2831 DRC_CONSTRAINT constraint;
2832 int clearance;
2833 BOARD_CONNECTED_ITEM* connectedItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( aOther );
2834 ZONE* zone = dynamic_cast<ZONE*>( aOther );
2835
2836 if( zone && zone->GetIsRuleArea() )
2837 {
2838 if( zone->GetDoNotAllowVias() )
2839 return zone->Outline()->Collide( aVia->GetPosition(), aVia->GetWidth() / 2 );
2840
2841 return false;
2842 }
2843
2844 if( connectedItem )
2845 {
2846 int connectedItemNet = connectedItem->GetNetCode();
2847
2848 if( connectedItemNet == 0 || connectedItemNet == aVia->GetNetCode() )
2849 return false;
2850 }
2851
2852 for( PCB_LAYER_ID layer : aOther->GetLayerSet().Seq() )
2853 {
2854 // Bitmaps are "on" a copper layer but are not actually part of it
2855 if( !IsCopperLayer( layer ) || aOther->Type() == PCB_BITMAP_T )
2856 continue;
2857
2858 constraint = m_drcEngine->EvalRules( CLEARANCE_CONSTRAINT, aVia, aOther, layer );
2859 clearance = constraint.GetValue().Min();
2860
2861 if( clearance >= 0 )
2862 {
2863 std::shared_ptr<SHAPE> viaShape = aVia->GetEffectiveShape( layer );
2864 std::shared_ptr<SHAPE> otherShape = aOther->GetEffectiveShape( layer );
2865
2866 if( viaShape->Collide( otherShape.get(), clearance - m_drcEpsilon ) )
2867 return true;
2868 }
2869 }
2870
2871 if( aOther->HasHole() )
2872 {
2873 constraint = m_drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, aVia, aOther,
2875 clearance = constraint.GetValue().Min();
2876
2877 if( clearance >= 0 )
2878 {
2879 std::shared_ptr<SHAPE> viaShape = aVia->GetEffectiveShape( UNDEFINED_LAYER );
2880
2881 if( viaShape->Collide( aOther->GetEffectiveHoleShape().get(),
2882 clearance - m_drcEpsilon ) )
2883 {
2884 return true;
2885 }
2886 }
2887 }
2888
2889 return false;
2890 }
2891
2892 bool checkDRCViolation( PCB_VIA* aVia )
2893 {
2894 std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> items;
2895 std::set<BOARD_ITEM*> checkedItems;
2896 BOX2I bbox = aVia->GetBoundingBox();
2897
2898 bbox.Inflate( m_worstClearance );
2899 m_frame->GetCanvas()->GetView()->Query( bbox, items );
2900
2901 for( std::pair<KIGFX::VIEW_ITEM*, int> it : items )
2902 {
2903 BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( it.first );
2904
2905 if( !item )
2906 continue;
2907
2908 if( ( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
2909 && !static_cast<ZONE*>( item )->GetIsRuleArea() )
2910 {
2911 continue; // stitching vias bind to zones, so ignore them
2912 }
2913 else if( item->Type() == PCB_FOOTPRINT_T || item->Type() == PCB_GROUP_T )
2914 {
2915 continue; // check against children, but not against footprint itself
2916 }
2917 else if( item->Type() == PCB_FP_TEXT_T
2918 && !static_cast<FP_TEXT*>( item )->IsVisible() )
2919 {
2920 continue; // ignore hidden items
2921 }
2922 else if( checkedItems.count( item ) )
2923 {
2924 continue; // already checked
2925 }
2926
2927 if( hasDRCViolation( aVia, item ) )
2928 return true;
2929
2930 checkedItems.insert( item );
2931 }
2932
2933 DRC_CONSTRAINT constraint = m_drcEngine->EvalRules( DISALLOW_CONSTRAINT, aVia, nullptr,
2935
2936 if( constraint.m_DisallowFlags && constraint.GetSeverity() != RPT_SEVERITY_IGNORE )
2937 return true;
2938
2939 return false;
2940 }
2941
2942 PAD* findPad( PCB_VIA* aVia )
2943 {
2944 const VECTOR2I position = aVia->GetPosition();
2945 const LSET lset = aVia->GetLayerSet();
2946
2947 for( FOOTPRINT* fp : m_board->Footprints() )
2948 {
2949 for( PAD* pad : fp->Pads() )
2950 {
2951 if( pad->HitTest( position ) && ( pad->GetLayerSet() & lset ).any() )
2952 {
2953 if( pad->GetNetCode() > 0 )
2954 return pad;
2955 }
2956 }
2957 }
2958
2959 return nullptr;
2960 }
2961
2962 int findStitchedZoneNet( PCB_VIA* aVia )
2963 {
2964 const VECTOR2I position = aVia->GetPosition();
2965 const LSET lset = aVia->GetLayerSet();
2966
2967 // first take the net of the active layer
2968 if( lset.test( m_frame->GetActiveLayer() ) )
2969 {
2970 for( ZONE* z : m_board->Zones() )
2971 {
2972 if( z->IsOnLayer( m_frame->GetActiveLayer() ) )
2973 {
2974 if( z->HitTestFilledArea( m_frame->GetActiveLayer(), position ) )
2975 return z->GetNetCode();
2976 }
2977 }
2978 }
2979
2980 // none? take the topmost visible layer
2981 for( PCB_LAYER_ID layer : LSET( m_board->GetVisibleLayers() & lset ).Seq() )
2982 {
2983 for( ZONE* z : m_board->Zones() )
2984 {
2985 if( z->IsOnLayer( layer ) )
2986 {
2987 if( z->HitTestFilledArea( layer, position ) )
2988 return z->GetNetCode();
2989 }
2990 }
2991 }
2992
2993 return -1;
2994 }
2995
2996 void SnapItem( BOARD_ITEM *aItem ) override
2997 {
2998 m_gridHelper.SetSnap( !( m_modifiers & MD_SHIFT ) );
2999
3001 PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
3002 VECTOR2I position = via->GetPosition();
3003
3004 if( settings->tracks == MAGNETIC_OPTIONS::CAPTURE_ALWAYS && m_gridHelper.GetSnap() )
3005 {
3006 PCB_TRACK* track = findTrack( via );
3007
3008 if( track )
3009 {
3010 SEG trackSeg( track->GetStart(), track->GetEnd() );
3011 VECTOR2I snap = m_gridHelper.AlignToSegment( position, trackSeg );
3012
3013 aItem->SetPosition( snap );
3014 }
3015 }
3016 else if( settings->pads == MAGNETIC_OPTIONS::CAPTURE_ALWAYS && m_gridHelper.GetSnap() )
3017 {
3018 PAD* pad = findPad( via );
3019
3020 if( pad )
3021 {
3022 aItem->SetPosition( pad->GetPosition() );
3023 }
3024 }
3025 }
3026
3027 bool PlaceItem( BOARD_ITEM* aItem, BOARD_COMMIT& aCommit ) override
3028 {
3029 WX_INFOBAR* infobar = m_frame->GetInfoBar();
3030 PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
3031 VECTOR2I viaPos = via->GetPosition();
3032 PCB_TRACK* track = findTrack( via );
3033 PAD* pad = findPad( via );
3034
3035 if( track )
3036 {
3037 via->SetNetCode( track->GetNetCode() );
3038 via->SetIsFree( false );
3039 }
3040 else if( pad )
3041 {
3042 via->SetNetCode( pad->GetNetCode() );
3043 via->SetIsFree( false );
3044 }
3045 else
3046 {
3047 via->SetNetCode( findStitchedZoneNet( via ) );
3048 via->SetIsFree( via->GetNetCode() > 0 );
3049 }
3050
3051 if( checkDRCViolation( via ) )
3052 {
3053 m_frame->ShowInfoBarError( _( "Via location violates DRC." ), true,
3055
3056 if( !m_allowDRCViolations )
3057 return false;
3058 }
3059 else
3060 {
3062 infobar->Dismiss();
3063 }
3064
3065 aCommit.Add( via );
3066
3067 // If the user explicitly disables snap (using shift), then don't break the tracks into
3068 // a chevron. This will prevent PNS from being able to connect the via and track but
3069 // it is explicitly requested by the user
3070 if( track && m_gridHelper.GetSnap() )
3071 {
3072 VECTOR2I trackStart = track->GetStart();
3073 VECTOR2I trackEnd = track->GetEnd();
3074 SEG trackSeg( trackStart, trackEnd );
3075
3076 OPT_VECTOR2I joint1;
3077 OPT_VECTOR2I joint2;
3078
3079 auto insertChevron =
3080 [&]()
3081 {
3082 if( ( trackStart - *joint1 ).SquaredEuclideanNorm()
3083 > ( trackStart - *joint2 ).SquaredEuclideanNorm() )
3084 {
3085 std::swap( joint1, joint2 );
3086 }
3087
3088 aCommit.Modify( track );
3089 track->SetStart( trackStart );
3090 track->SetEnd( *joint1 );
3091
3092 PCB_TRACK* newTrack = dynamic_cast<PCB_TRACK*>( track->Clone() );
3093 wxCHECK( newTrack, /* void */ );
3094 const_cast<KIID&>( newTrack->m_Uuid ) = KIID();
3095
3096 newTrack->SetStart( *joint1 );
3097 newTrack->SetEnd( viaPos );
3098 aCommit.Add( newTrack );
3099
3100 newTrack = dynamic_cast<PCB_TRACK*>( track->Clone() );
3101 wxCHECK( newTrack, /* void */ );
3102 const_cast<KIID&>( newTrack->m_Uuid ) = KIID();
3103
3104 newTrack->SetStart( viaPos );
3105 newTrack->SetEnd( *joint2 );
3106 aCommit.Add( newTrack );
3107
3108 newTrack = dynamic_cast<PCB_TRACK*>( track->Clone() );
3109 wxCHECK( newTrack, /* void */ );
3110 const_cast<KIID&>( newTrack->m_Uuid ) = KIID();
3111
3112 newTrack->SetStart( *joint2 );
3113 newTrack->SetEnd( trackEnd );
3114 aCommit.Add( newTrack );
3115 };
3116
3117 if( viaPos == trackStart || viaPos == trackEnd )
3118 return true;
3119
3120 if( trackStart.x == trackEnd.x )
3121 {
3122 VECTOR2I splitPt = trackSeg.NearestPoint( viaPos );
3123
3124 if( splitPt.x != viaPos.x
3125 && abs( splitPt.x - viaPos.x ) < abs( splitPt.y - trackStart.y )
3126 && abs( splitPt.x - viaPos.x ) < abs( splitPt.y - trackEnd.y ) )
3127 {
3128 int offset = abs( splitPt.x - viaPos.x );
3129
3130 joint1 = VECTOR2I( splitPt.x, splitPt.y - offset );
3131 joint2 = VECTOR2I( splitPt.x, splitPt.y + offset );
3132
3133 insertChevron();
3134 return true;
3135 }
3136 }
3137 else if( trackStart.y == trackEnd.y )
3138 {
3139 VECTOR2I splitPt = trackSeg.NearestPoint( viaPos );
3140
3141 if( splitPt.y != viaPos.y
3142 && abs( trackStart.y - viaPos.y ) < abs( trackStart.x - viaPos.x )
3143 && abs( trackEnd.y - viaPos.y ) < abs( trackEnd.x - viaPos.x ) )
3144 {
3145 int offset = abs( splitPt.y - viaPos.y );
3146
3147 joint1 = VECTOR2I( splitPt.x - offset, splitPt.y );
3148 joint2 = VECTOR2I( splitPt.x + offset, splitPt.y );
3149
3150 insertChevron();
3151 return true;
3152 }
3153 }
3154 else if( abs( trackStart.y - trackEnd.y ) == abs( trackStart.x - trackEnd.x ) )
3155 {
3156 SEG horiz( VECTOR2I( -INT_MAX, viaPos.y ), VECTOR2I( INT_MAX, viaPos.y ) );
3157 SEG vert( VECTOR2I( viaPos.x, -INT_MAX ), VECTOR2I( viaPos.x, INT_MAX ) );
3158
3159 if( track->GetBoundingBox().Contains( viaPos ) )
3160 {
3161 joint1 = trackSeg.Intersect( horiz, true, true );
3162 joint2 = trackSeg.Intersect( vert, true, true );
3163
3164 if( !joint1 || !joint2 )
3165 return false;
3166
3167 insertChevron();
3168 return true;
3169 }
3170 }
3171
3172 aCommit.Modify( track );
3173 track->SetStart( trackStart );
3174 track->SetEnd( viaPos );
3175
3176 PCB_TRACK* newTrack = dynamic_cast<PCB_TRACK*>( track->Clone() );
3177 const_cast<KIID&>( newTrack->m_Uuid ) = KIID();
3178
3179 newTrack->SetStart( viaPos );
3180 newTrack->SetEnd( trackEnd );
3181 aCommit.Add( newTrack );
3182 }
3183
3184 return true;
3185 }
3186
3187 std::unique_ptr<BOARD_ITEM> CreateItem() override
3188 {
3190 PCB_VIA* via = new PCB_VIA( m_board );
3191
3192 via->SetNetCode( 0 );
3193 via->SetViaType( bds.m_CurrentViaType );
3194
3195 // for microvias, the size and hole will be changed later.
3196 via->SetWidth( bds.GetCurrentViaSize() );
3197 via->SetDrill( bds.GetCurrentViaDrill() );
3198
3199 // Usual via is from copper to component.
3200 // layer pair is B_Cu and F_Cu.
3201 via->SetLayerPair( B_Cu, F_Cu );
3202
3203 PCB_LAYER_ID first_layer = m_frame->GetActiveLayer();
3204 PCB_LAYER_ID last_layer;
3205
3206 // prepare switch to new active layer:
3207 if( first_layer != m_frame->GetScreen()->m_Route_Layer_TOP )
3208 last_layer = m_frame->GetScreen()->m_Route_Layer_TOP;
3209 else
3210 last_layer = m_frame->GetScreen()->m_Route_Layer_BOTTOM;
3211
3212 // Adjust the actual via layer pair
3213 switch( via->GetViaType() )
3214 {
3216 via->SetLayerPair( first_layer, last_layer );
3217 break;
3218
3219 case VIATYPE::MICROVIA: // from external to the near neighbor inner layer
3220 {
3221 PCB_LAYER_ID last_inner_layer =
3223
3224 if( first_layer == B_Cu )
3225 last_layer = last_inner_layer;
3226 else if( first_layer == F_Cu )
3227 last_layer = In1_Cu;
3228 else if( first_layer == last_inner_layer )
3229 last_layer = B_Cu;
3230 else if( first_layer == In1_Cu )
3231 last_layer = F_Cu;
3232
3233 // else error: will be removed later
3234 via->SetLayerPair( first_layer, last_layer );
3235
3236 // Update diameter and hole size, which where set previously for normal vias
3237 NETCLASS* netClass = via->GetEffectiveNetClass();
3238
3239 via->SetWidth( netClass->GetuViaDiameter() );
3240 via->SetDrill( netClass->GetuViaDrill() );
3241 }
3242 break;
3243
3244 default:
3245 break;
3246 }
3247
3248 return std::unique_ptr<BOARD_ITEM>( via );
3249 }
3250 };
3251
3252 VIA_PLACER placer( frame() );
3253
3254 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::VIA );
3255
3256 doInteractiveItemPlacement( aEvent, &placer, _( "Place via" ), IPO_REPEAT | IPO_SINGLE_CLICK );
3257
3258 return 0;
3259}
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
VIATYPE m_CurrentViaType
(VIA_BLIND_BURIED, VIA_THROUGH, VIA_MICROVIA)
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: board_item.cpp:219
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:197
virtual std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape() const
Definition: board_item.cpp:229
virtual bool HasHole() const
Definition: board_item.h:140
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
Definition: board.cpp:601
ZONES & Zones()
Definition: board.h:317
FOOTPRINTS & Footprints()
Definition: board.h:311
int GetCopperLayerCount() const
Definition: board.cpp:563
bool Contains(const Vec &aPoint) const
Definition: box2.h:141
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
COMMIT & Add(EDA_ITEM *aItem)
Notify observers that aItem has been added.
Definition: commit.h:78
int m_DisallowFlags
Definition: drc_rule.h:173
SEVERITY GetSeverity() const
Definition: drc_rule.h:162
const MINOPTMAX< int > & GetValue() const
Definition: drc_rule.h:141
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...
WX_INFOBAR * GetInfoBar()
virtual void SetPosition(const VECTOR2I &aPos)
Definition: eda_item.h:250
const KIID m_Uuid
Definition: eda_item.h:492
PADS & Pads()
Definition: footprint.h:170
bool GetSnap() const
Definition: grid_helper.h:66
void SetSnap(bool aSnap)
Definition: grid_helper.h:65
virtual int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Find all visible items that touch or are within the rectangle aRect.
Definition: view.cpp:425
std::pair< VIEW_ITEM *, int > LAYER_ITEM_PAIR
Definition: view.h:73
Definition: kiid.h:48
LSET is a set of PCB_LAYER_IDs.
Definition: layer_ids.h:532
LSEQ Seq(const PCB_LAYER_ID *aWishListSequence, unsigned aCount) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition: lset.cpp:411
T Min() const
Definition: minoptmax.h:33
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
Definition: pad.h:60
Common, abstract interface for edit frames.
wxString GetDesignRulesPath()
Return the absolute path to the design rules file for the currently-loaded board.
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
VECTOR2I AlignToSegment(const VECTOR2I &aPoint, const SEG &aSeg)
PCB_LAYER_ID m_Route_Layer_TOP
Definition: pcb_screen.h:43
PCB_LAYER_ID m_Route_Layer_BOTTOM
Definition: pcb_screen.h:44
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...
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
virtual EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_track.cpp:61
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_track.cpp:268
const VECTOR2I & GetStart() const
Definition: pcb_track.h:114
const VECTOR2I & GetEnd() const
Definition: pcb_track.h:111
VECTOR2I GetPosition() const override
Definition: pcb_track.h:442
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pcb_track.cpp:1192
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: pcb_track.cpp:507
ROUTING_SETTINGS & Settings()
Definition: pns_router.h:189
ROUTER * Router() const
Definition: seg.h:42
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
A modified version of the wxInfoBar class that allows us to:
Definition: wx_infobar.h:75
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
Definition: wx_infobar.cpp:175
MESSAGE_TYPE GetMessageType() const
Definition: wx_infobar.h:100
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:703
bool GetDoNotAllowVias() const
Definition: zone.h:705
SHAPE_POLY_SET * Outline()
Definition: zone.h:318
@ DISALLOW_CONSTRAINT
Definition: drc_rule.h:62
@ CLEARANCE_CONSTRAINT
Definition: drc_rule.h:47
@ HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:48
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:827
@ B_Cu
Definition: layer_ids.h:95
@ In1_Cu
Definition: layer_ids.h:65
@ F_Cu
Definition: layer_ids.h:64
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
@ BLIND_BURIED
BOARD * GetBoard()
@ RPT_SEVERITY_IGNORE
std::optional< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
MAGNETIC_OPTIONS tracks
MAGNETIC_OPTIONS pads
A filename or source description, a problem input line, a line number, a byte offset,...
Definition: ki_exception.h:119
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:129
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129
@ 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_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_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92

References _, std::abs(), COMMIT::Add(), PCB_GRID_HELPER::AlignToSegment(), PNS::ROUTING_SETTINGS::AllowDRCViolations(), B_Cu, BLIND_BURIED, CAPTURE_ALWAYS, CLEARANCE_CONSTRAINT, PCB_TRACK::Clone(), SHAPE_POLY_SET::Collide(), BOX2< Vec >::Contains(), DISALLOW_CONSTRAINT, WX_INFOBAR::Dismiss(), PCB_TOOL_BASE::doInteractiveItemPlacement(), WX_INFOBAR::DRC_VIOLATION, EuclideanNorm(), F_Cu, PCB_TOOL_BASE::footprint(), BOARD::Footprints(), PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetActiveLayer(), PCB_BASE_FRAME::GetBoard(), PCB_TRACK::GetBoundingBox(), PCB_BASE_FRAME::GetCanvas(), BOARD::GetCopperLayerCount(), BOARD_DESIGN_SETTINGS::GetCurrentViaDrill(), BOARD_DESIGN_SETTINGS::GetCurrentViaSize(), PCB_BASE_EDIT_FRAME::GetDesignRulesPath(), BOARD::GetDesignSettings(), ZONE::GetDoNotAllowVias(), BOARD_DESIGN_SETTINGS::GetDRCEpsilon(), BOARD_ITEM::GetEffectiveHoleShape(), BOARD_ITEM::GetEffectiveShape(), PCB_VIA::GetEffectiveShape(), PCB_TRACK::GetEnd(), EDA_BASE_FRAME::GetInfoBar(), ZONE::GetIsRuleArea(), BOARD_ITEM::GetLayerSet(), PCB_VIA::GetLayerSet(), PCB_BASE_FRAME::GetMagneticItemsSettings(), WX_INFOBAR::GetMessageType(), BOARD_CONNECTED_ITEM::GetNetCode(), PCB_VIA::GetPosition(), PCB_BASE_FRAME::GetScreen(), DRC_CONSTRAINT::GetSeverity(), GRID_HELPER::GetSnap(), PCB_TRACK::GetStart(), TOOL_MANAGER::GetTool(), TOOLS_HOLDER::GetToolManager(), NETCLASS::GetuViaDiameter(), NETCLASS::GetuViaDrill(), DRC_CONSTRAINT::GetValue(), PCB_DRAW_PANEL_GAL::GetView(), BOARD::GetVisibleLayers(), PCB_TRACK::GetWidth(), BOARD_ITEM::HasHole(), HOLE_CLEARANCE_CONSTRAINT, In1_Cu, BOX2< Vec >::Inflate(), SEG::Intersect(), PCB_TOOL_BASE::IPO_REPEAT, PCB_TOOL_BASE::IPO_SINGLE_CLICK, IsCopperLayer(), m_board, BOARD_DESIGN_SETTINGS::m_CurrentViaType, DRC_CONSTRAINT::m_DisallowFlags, BOARD_DESIGN_SETTINGS::m_DRCEngine, m_frame, PCB_TOOL_BASE::m_isFootprintEditor, m_mode, PCB_SCREEN::m_Route_Layer_BOTTOM, PCB_SCREEN::m_Route_Layer_TOP, EDA_ITEM::m_Uuid, MD_SHIFT, MICROVIA, MINOPTMAX< T >::Min(), COMMIT::Modify(), SEG::NearestPoint(), ZONE::Outline(), pad, FOOTPRINT::Pads(), MAGNETIC_SETTINGS::pads, PCB_BITMAP_T, PCB_FOOTPRINT_T, PCB_FP_TEXT_T, PCB_FP_ZONE_T, PCB_GROUP_T, PCB_ZONE_T, KIGFX::VIEW::Query(), PNS::TOOL_BASE::Router(), RPT_SEVERITY_IGNORE, LSET::Seq(), PCB_TRACK::SetEnd(), EDA_ITEM::SetPosition(), GRID_HELPER::SetSnap(), PCB_TRACK::SetStart(), PNS::ROUTER::Settings(), EDA_BASE_FRAME::ShowInfoBarError(), TestSegmentHit(), ToLAYER_ID(), MAGNETIC_SETTINGS::tracks, EDA_ITEM::Type(), UNDEFINED_LAYER, via, VIA, PCB_TOOL_BASE::view(), VECTOR2< T >::x, VECTOR2< T >::y, and BOARD::Zones().

Referenced by setTransitions().

◆ DrawZone()

int DRAWING_TOOL::DrawZone ( const TOOL_EVENT aEvent)

Start interactively drawing a zone.

After invoking the function a zone settings dialog is displayed. After confirmation it allows the user to set points that are going to be used as a boundary polygon of the zone. Double click or clicking on the origin of the boundary polyline finishes the drawing.

The event parameter indicates which type of zone to draw:

  • ADD add a new zone/keepout with fresh settings.
  • CUTOUT add a cutout to an existing zone.
  • SIMILAR add a new zone with the same settings as an existing one.

Definition at line 2501 of file drawing_tool.cpp.

2502{
2504 return 0;
2505
2506 ZONE_MODE zoneMode = aEvent.Parameter<ZONE_MODE>();
2507 MODE drawMode = MODE::ZONE;
2508
2509 if( aEvent.IsAction( &PCB_ACTIONS::drawRuleArea ) )
2510 drawMode = MODE::KEEPOUT;
2511
2512 if( aEvent.IsAction( &PCB_ACTIONS::drawPolygon ) )
2513 drawMode = MODE::GRAPHIC_POLYGON;
2514
2515 SCOPED_DRAW_MODE scopedDrawMode( m_mode, drawMode );
2516
2517 // get a source zone, if we need one. We need it for:
2518 // ZONE_MODE::CUTOUT (adding a hole to the source zone)
2519 // ZONE_MODE::SIMILAR (creating a new zone using settings of source zone
2520 ZONE* sourceZone = nullptr;
2521
2522 if( !getSourceZoneForAction( zoneMode, &sourceZone ) )
2523 return 0;
2524
2525 // Turn zones on if they are off, so that the created object will be visible after completion
2527
2529
2530 params.m_keepout = drawMode == MODE::KEEPOUT;
2531 params.m_mode = zoneMode;
2532 params.m_sourceZone = sourceZone;
2533
2534 if( zoneMode == ZONE_MODE::SIMILAR )
2535 params.m_layer = sourceZone->GetLayer();
2536 else
2537 params.m_layer = m_frame->GetActiveLayer();
2538
2539 ZONE_CREATE_HELPER zoneTool( *this, params );
2540 // the geometry manager which handles the zone geometry, and hands the calculated points
2541 // over to the zone creator tool
2542 POLYGON_GEOM_MANAGER polyGeomMgr( zoneTool );
2543 bool started = false;
2545
2546 m_frame->PushTool( aEvent );
2547
2548 auto setCursor =
2549 [&]()
2550 {
2552 };
2553
2554 auto cleanup =
2555 [&] ()
2556 {
2557 polyGeomMgr.Reset();
2558 started = false;
2559 grid.ClearSkipPoint();
2560 m_controls->SetAutoPan( false );
2561 m_controls->CaptureCursor( false );
2562 };
2563
2564 Activate();
2565 // Must be done after Activate() so that it gets set into the correct context
2566 m_controls->ShowCursor( true );
2568 // Set initial cursor
2569 setCursor();
2570
2571 if( aEvent.HasPosition() )
2572 m_toolMgr->PrimeTool( aEvent.Position() );
2573
2574 // Main loop: keep receiving events
2575 while( TOOL_EVENT* evt = Wait() )
2576 {
2577 setCursor();
2578
2579 LSET layers( m_frame->GetActiveLayer() );
2580 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
2581 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
2582
2583 VECTOR2I cursorPos = evt->HasPosition() ? evt->Position() : m_controls->GetMousePosition();
2584 cursorPos = GetClampedCoords( grid.BestSnapAnchor( cursorPos, layers ), COORDS_PADDING );
2585
2586 m_controls->ForceCursorPosition( true, cursorPos );
2587
2588 polyGeomMgr.SetLeaderMode( Is45Limited() ? POLYGON_GEOM_MANAGER::LEADER_MODE::DEG45
2590
2591 if( evt->IsCancelInteractive() )
2592 {
2593 if( polyGeomMgr.IsPolygonInProgress() )
2594 {
2595 cleanup();
2596 }
2597 else
2598 {
2599 // We've handled the cancel event. Don't cancel other tools
2600 evt->SetPassEvent( false );
2601 m_frame->PopTool( aEvent );
2602 break;
2603 }
2604 }
2605 else if( evt->IsActivate() )
2606 {
2607 if( polyGeomMgr.IsPolygonInProgress() )
2608 cleanup();
2609
2610 if( evt->IsPointEditor() )
2611 {
2612 // don't exit (the point editor runs in the background)
2613 }
2614 else if( evt->IsMoveTool() )
2615 {
2616 // leave ourselves on the stack so we come back after the move
2617 break;
2618 }
2619 else
2620 {
2621 m_frame->PopTool( aEvent );
2622 break;
2623 }
2624 }
2625 else if( evt->IsAction( &PCB_ACTIONS::layerChanged ) )
2626 {
2627 if( zoneMode != ZONE_MODE::SIMILAR )
2628 params.m_layer = frame()->GetActiveLayer();
2629
2630 if( !m_view->IsLayerVisible( params.m_layer ) )
2631 {
2634 }
2635 }
2636 else if( evt->IsClick( BUT_RIGHT ) )
2637 {
2639 }
2640 // events that lock in nodes
2641 else if( evt->IsClick( BUT_LEFT )
2642 || evt->IsDblClick( BUT_LEFT )
2643 || evt->IsAction( &PCB_ACTIONS::closeOutline ) )
2644 {
2645 // Check if it is double click / closing line (so we have to finish the zone)
2646 const bool endPolygon = evt->IsDblClick( BUT_LEFT )
2647 || evt->IsAction( &PCB_ACTIONS::closeOutline )
2648 || polyGeomMgr.NewPointClosesOutline( cursorPos );
2649
2650 if( endPolygon )
2651 {
2652 polyGeomMgr.SetFinished();
2653 polyGeomMgr.Reset();
2654
2655 started = false;
2656 m_controls->SetAutoPan( false );
2657 m_controls->CaptureCursor( false );
2658 }
2659 // adding a corner
2660 else if( polyGeomMgr.AddPoint( cursorPos ) )
2661 {
2662 if( !started )
2663 {
2664 started = true;
2665
2666 m_controls->SetAutoPan( true );
2667 m_controls->CaptureCursor( true );
2668
2669 if( !m_view->IsLayerVisible( params.m_layer ) )
2670 {
2673 }
2674 }
2675 }
2676 }
2677 else if( evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) )
2678 {
2679 polyGeomMgr.DeleteLastCorner();
2680
2681 if( !polyGeomMgr.IsPolygonInProgress() )
2682 {
2683 // report finished as an empty shape
2684 polyGeomMgr.SetFinished();
2685
2686 // start again
2687 started = false;
2688 m_controls->SetAutoPan( false );
2689 m_controls->CaptureCursor( false );
2690 }
2691 }
2692 else if( polyGeomMgr.IsPolygonInProgress()
2693 && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
2694 {
2695 polyGeomMgr.SetCursorPosition( cursorPos );
2696 }
2697 else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
2698 {
2699 wxBell();
2700 }
2701 else if( started&& evt->IsAction( &PCB_ACTIONS::properties ) )
2702 {
2703 frame()->OnEditItemRequest( zoneTool.GetZone() );
2704 zoneTool.OnGeometryChange( polyGeomMgr );
2705 frame()->SetMsgPanel( zoneTool.GetZone() );
2706 }
2707 /*else if( evt->IsAction( &ACTIONS::updateUnits ) )
2708 {
2709 // If we ever have an assistant here that reports dimensions, we'll want to
2710 // update its units here....
2711 // zoneAsst.SetUnits( frame()->GetUserUnits() );
2712 // m_view->Update( &zoneAsst );
2713 evt->SetPassEvent();
2714 }*/
2715 else
2716 {
2717 evt->SetPassEvent();
2718 }
2719
2720 } // end while
2721
2724 controls()->SetAutoPan( false );
2725 m_controls->CaptureCursor( false );
2726 return 0;
2727}
bool getSourceZoneForAction(ZONE_MODE aMode, ZONE **aZone)
Draw a polygon, that is added as a zone or a keepout area.
static TOOL_ACTION drawRuleArea
Definition: pcb_actions.h:185
static TOOL_ACTION drawPolygon
Definition: pcb_actions.h:171
static TOOL_ACTION closeOutline
Definition: pcb_actions.h:194
void SetObjectVisible(GAL_LAYER_ID aLayer, bool aVisible=true)
Class that handles the drawing of a polygon, including management of last corner deletion and drawing...
@ DIRECT
Unconstrained point-to-point.
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:442
An adjunct helper to the DRAWING_TOOL interactive tool, which handles incoming geometry changes from ...
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: zone.cpp:245
@ LAYER_ZONES
Control for copper zone opacity/visibility (color ignored)
Definition: layer_ids.h:231
ZONE_MODE
Definition: pcb_actions.h:34
@ SIMILAR
Add a new zone with the same settings as an existing one.
Parameters used to fully describe a zone creation process.
ZONE_MODE m_mode
Zone settings source (for similar and cutout zones)
bool m_keepout
< Should create a keepout zone?
ZONE * m_sourceZone
Zone leader mode.
PCB_LAYER_ID m_layer
The zone mode to operate in.

References TOOL_INTERACTIVE::Activate(), POLYGON_GEOM_MANAGER::AddPoint(), ARROW, BUT_LEFT, BUT_RIGHT, KIGFX::VIEW_CONTROLS::CaptureCursor(), PCB_ACTIONS::closeOutline, PCB_TOOL_BASE::controls(), COORDS_PADDING, POLYGON_GEOM_MANAGER::DEG45, POLYGON_GEOM_MANAGER::DeleteLastCorner(), PCB_ACTIONS::deleteLastPoint, POLYGON_GEOM_MANAGER::DIRECT, PCB_ACTIONS::drawPolygon, PCB_ACTIONS::drawRuleArea, KIGFX::VIEW_CONTROLS::ForceCursorPosition(), PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetActiveLayer(), PCB_BASE_EDIT_FRAME::GetAppearancePanel(), PCB_BASE_FRAME::GetCanvas(), GetClampedCoords(), ZONE::GetLayer(), PCB_BASE_FRAME::GetMagneticItemsSettings(), PCB_BASE_FRAME::GetModel(), KIGFX::VIEW_CONTROLS::GetMousePosition(), getSourceZoneForAction(), TOOL_BASE::getView(), ZONE_CREATE_HELPER::GetZone(), GRAPHIC_POLYGON, grid, TOOL_EVENT::HasPosition(), PCB_TOOL_BASE::Is45Limited(), TOOL_EVENT::IsAction(), KIGFX::VIEW::IsLayerVisible(), POLYGON_GEOM_MANAGER::IsPolygonInProgress(), ZONE_FILLER_TOOL::IsZoneFillAction(), KEEPOUT, LAYER_ZONES, PCB_ACTIONS::layerChanged, m_controls, m_frame, PCB_TOOL_BASE::m_isFootprintEditor, ZONE_CREATE_HELPER::PARAMS::m_keepout, ZONE_CREATE_HELPER::PARAMS::m_layer, TOOL_INTERACTIVE::m_menu, m_mode, ZONE_CREATE_HELPER::PARAMS::m_mode, ZONE_CREATE_HELPER::PARAMS::m_sourceZone, TOOL_BASE::m_toolMgr, m_view, MD_SHIFT, POLYGON_GEOM_MANAGER::NewPointClosesOutline(), PCB_BASE_EDIT_FRAME::OnEditItemRequest(), ZONE_CREATE_HELPER::OnGeometryChange(), TOOL_EVENT::Parameter(), PENCIL, TOOLS_HOLDER::PopTool(), TOOL_EVENT::Position(), TOOL_MANAGER::PrimeTool(), PCB_ACTIONS::properties, TOOLS_HOLDER::PushTool(), EDA_DRAW_PANEL_GAL::Refresh(), POLYGON_GEOM_MANAGER::Reset(), PCB_TOOL_BASE::selection(), KIGFX::VIEW_CONTROLS::SetAutoPan(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), POLYGON_GEOM_MANAGER::SetCursorPosition(), POLYGON_GEOM_MANAGER::SetFinished(), APPEARANCE_CONTROLS::SetLayerVisible(), POLYGON_GEOM_MANAGER::SetLeaderMode(), EDA_DRAW_FRAME::SetMsgPanel(), PCB_BASE_EDIT_FRAME::SetObjectVisible(), TOOL_MENU::ShowContextMenu(), KIGFX::VIEW_CONTROLS::ShowCursor(), SIMILAR, TOOL_INTERACTIVE::Wait(), and ZONE.

Referenced by setTransitions().

◆ footprint()

◆ 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(), EDIT_TOOL::copyToClipboard(), ROUTER_TOOL::CustomTrackWidthDialog(), FOOTPRINT_EDITOR_CONTROL::DeleteFootprint(), EDIT_TOOL::DeleteItems(), PCB_TOOL_BASE::displayOptions(), BOARD_EDITOR_CONTROL::doCrossProbePcbToSch(), PCB_TOOL_BASE::doInteractiveItemPlacement(), EDIT_TOOL::doMoveSelection(), ROUTER_TOOL::DpDimensionsDialog(), EDIT_TOOL::DragArcTrack(), drawArc(), DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), drawShape(), DrawVia(), DrawZone(), PAD_TOOL::EditPad(), PAD_TOOL::EnumeratePads(), PAD_TOOL::explodePad(), BOARD_EDITOR_CONTROL::ExportSpecctraDSN(), ZONE_FILLER_TOOL::FillAllZones(), EDIT_TOOL::FilletTracks(), ROUTER_TOOL::finishInteractive(), EDIT_TOOL::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(), EDIT_TOOL::Init(), ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), InteractivePlaceWithPreview(), PCB_TOOL_BASE::Is45Limited(), PCB_PICKER_TOOL::Main(), LENGTH_TUNER_TOOL::MainLoop(), ROUTER_TOOL::MainLoop(), LENGTH_TUNER_TOOL::meanderSettingsDialog(), EDIT_TOOL::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(), 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(), EDIT_TOOL::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(), ToggleHV45Mode(), PCB_CONTROL::ToggleRatsnest(), PCB_CONTROL::unfilledZoneCheck(), PCB_POINT_EDITOR::updateItem(), ROUTER_TOOL::UpdateMessagePanel(), EDIT_TOOL::updateModificationPoint(), BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB(), PCB_CONTROL::ZoneDisplayMode(), ZONE_FILLER_TOOL::ZoneFill(), ZONE_FILLER_TOOL::ZoneFillAll(), and ZONE_FILLER_TOOL::ZoneFillDirty().

◆ getClampedDifferenceEnd()

VECTOR2I DRAWING_TOOL::getClampedDifferenceEnd ( const VECTOR2I aOrigin,
const VECTOR2I aEnd 
)
inlineprivate

Clamps the end vector to respect numeric limits of difference representation.

Parameters
aOrigin- the origin vector.
aEnd- the end vector.
Returns
clamped end vector.

Definition at line 284 of file drawing_tool.h.

285 {
286 typedef std::numeric_limits<int> coord_limits;
287 const int guardValue = 1;
288
289 VECTOR2I::extended_type maxDiff = coord_limits::max() - guardValue;
290
291 VECTOR2I::extended_type xDiff = VECTOR2I::extended_type( aEnd.x ) - aOrigin.x;
292 VECTOR2I::extended_type yDiff = VECTOR2I::extended_type( aEnd.y ) - aOrigin.y;
293
294 if( xDiff > maxDiff )
295 xDiff = maxDiff;
296 if( yDiff > maxDiff )
297 yDiff = maxDiff;
298
299 if( xDiff < -maxDiff )
300 xDiff = -maxDiff;
301 if( yDiff < -maxDiff )
302 yDiff = -maxDiff;
303
304 return aOrigin + VECTOR2I( int( xDiff ), int( yDiff ) );
305 }
VECTOR2_TRAITS< int >::extended_type extended_type
Definition: vector2d.h:72

References VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by drawShape().

◆ getClampedRadiusEnd()

VECTOR2I DRAWING_TOOL::getClampedRadiusEnd ( const VECTOR2I aOrigin,
const VECTOR2I aEnd 
)
inlineprivate

Clamps the end vector to respect numeric limits of radius representation.

Parameters
aOrigin- the origin vector.
aEnd- the end vector.
Returns
clamped end vector. Return the appropriate width for a segment depending on the settings.

Definition at line 314 of file drawing_tool.h.

References VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by drawShape().

◆ GetDrawingMode()

DRAWING_TOOL::MODE DRAWING_TOOL::GetDrawingMode ( ) const

Return the current drawing mode of the DRAWING_TOOL or #MODE::NONE if not currently in any drawing mode.

Definition at line 279 of file drawing_tool.cpp.

280{
281 return m_mode;
282}

References m_mode.

Referenced by BOARD_EDITOR_CONTROL::Init().

◆ 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().

◆ getSegmentWidth()

int DRAWING_TOOL::getSegmentWidth ( PCB_LAYER_ID  aLayer) const
private

Definition at line 3262 of file drawing_tool.cpp.

3263{
3264 assert( m_board );
3265 return m_board->GetDesignSettings().GetLineThickness( aLayer );
3266}

References BOARD::GetDesignSettings(), BOARD_DESIGN_SETTINGS::GetLineThickness(), and m_board.

Referenced by drawArc(), and drawShape().

◆ getSourceZoneForAction()

bool DRAWING_TOOL::getSourceZoneForAction ( ZONE_MODE  aMode,
ZONE **  aZone 
)
private

Draw a polygon, that is added as a zone or a keepout area.

Parameters
aKeepoutdictates if the drawn polygon is a zone or a keepout area.
aModedictates the mode of the zone tool:
  • ADD add a new zone/keepout with fresh settings
  • CUTOUT add a cutout to an existing zone
  • SIMILAR add a new zone with the same settings as an existing one Get a source zone item for an action that takes an existing zone into account (for example a cutout of an existing zone).

The source zone is taken from the current selection.

Parameters
aModemode of the zone tool
aZoneupdated pointer to a suitable source zone, or nullptr if none found, or the action doesn't need a source
Returns
true if a suitable zone was found, or the action doesn't need a zone. False if the action needs a zone but none was found.

Definition at line 2467 of file drawing_tool.cpp.

2468{
2469 bool clearSelection = false;
2470 *aZone = nullptr;
2471
2472 // not an action that needs a source zone
2473 if( aMode == ZONE_MODE::ADD || aMode == ZONE_MODE::GRAPHIC_POLYGON )
2474 return true;
2475
2477 const PCB_SELECTION& selection = selTool->GetSelection();
2478
2479 if( selection.Empty() )
2480 {
2481 clearSelection = true;
2483 }
2484
2485 // we want a single zone
2486 if( selection.Size() == 1 )
2487 *aZone = dyn_cast<ZONE*>( selection[0] );
2488
2489 // expected a zone, but didn't get one
2490 if( !*aZone )
2491 {
2492 if( clearSelection )
2494
2495 return false;
2496 }
2497
2498 return true;
2499}
static TOOL_ACTION selectionCursor
Select a single item under the cursor position.
Definition: pcb_actions.h:56
The selection tool: currently supports:
PCB_SELECTION & GetSelection()
int Size() const
Returns the number of selected parts.
Definition: selection.h:115
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:109
@ ADD
Add a new zone/keepout with fresh settings.

References ADD, SELECTION::Empty(), PCB_SELECTION_TOOL::GetSelection(), TOOL_MANAGER::GetTool(), GRAPHIC_POLYGON, TOOL_BASE::m_toolMgr, TOOL_MANAGER::RunAction(), PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_ACTIONS::selectionCursor, and SELECTION::Size().

Referenced by DrawZone().

◆ 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}
KIGFX::VIEW * GetView() const
Definition: tool_manager.h:285

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(), EDIT_TOOL::DeleteItems(), PL_EDIT_TOOL::DoDelete(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), PCB_TOOL_BASE::doInteractiveItemPlacement(), EDIT_TOOL::doMoveSelection(), SELECTION_TOOL::doSelectionMenu(), COMMON_TOOLS::doZoomFit(), COMMON_TOOLS::doZoomInOut(), COMMON_TOOLS::doZoomToPreset(), EDIT_TOOL::DragArcTrack(), drawArc(), DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), SCH_LINE_WIRE_BUS_TOOL::DrawSegments(), PL_DRAWING_TOOLS::DrawShape(), drawShape(), 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(), EDIT_TOOL::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(), EDIT_TOOL::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(), PlaceImage(), PlaceImportedGraphics(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), PlaceText(), ROUTER_TOOL::prepareInteractive(), SCH_EDIT_TOOL::Properties(), EDIT_TOOL::Properties(), EE_SELECTION_TOOL::Reset(), EE_TOOL_BASE< T >::Reset(), GERBVIEW_SELECTION_TOOL::Reset(), PNS::TOOL_BASE::Reset(), BOARD_EDITOR_CONTROL::Reset(), 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(), 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(), EDIT_TOOL::copyToClipboard(), COMMON_TOOLS::CursorControl(), EDIT_TOOL::DeleteItems(), SCH_LINE_WIRE_BUS_TOOL::doDrawSegments(), EDIT_TOOL::doMoveSelection(), SCH_LINE_WIRE_BUS_TOOL::doUnfoldBus(), COMMON_TOOLS::doZoomToPreset(), EDIT_TOOL::DragArcTrack(), DrawCircle(), DrawLine(), MICROWAVE_TOOL::drawMicrowaveInductor(), 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(), EDIT_TOOL::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(), PlaceImage(), PL_DRAWING_TOOLS::PlaceItem(), SCH_DRAWING_TOOLS::PlaceSymbol(), SCH_EDIT_TOOL::Properties(), EDIT_TOOL::Properties(), SCH_EDIT_TOOL::RepeatDrawItem(), PL_SELECTION_TOOL::RequestSelection(), EE_SELECTION_TOOL::RequestSelection(), 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(), setTransitions(), DRC_TOOL::setTransitions(), EDIT_TOOL::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 DRAWING_TOOL::Init ( )
overridevirtual

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

Returns
True if the initialization went fine, false - otherwise.

Reimplemented from PCB_TOOL_BASE.

Definition at line 186 of file drawing_tool.cpp.

187{
188 auto haveHighlight =
189 [&]( const SELECTION& sel )
190 {
192
193 return !cfg->GetHighlightNetCodes().empty();
194 };
195
196 auto activeToolFunctor =
197 [this]( const SELECTION& aSel )
198 {
199 return m_mode != MODE::NONE;
200 };
201
202 // some interactive drawing tools can undo the last point
203 auto canUndoPoint =
204 [this]( const SELECTION& aSel )
205 {
206 return ( m_mode == MODE::ARC
207 || m_mode == MODE::ZONE
210 };
211
212 // functor for tools that can automatically close the outline
213 auto canCloseOutline =
214 [this]( const SELECTION& aSel )
215 {
216 return ( m_mode == MODE::ZONE
219 };
220
221 auto arcToolActive =
222 [this]( const SELECTION& aSel )
223 {
224 return m_mode == MODE::ARC;
225 };
226
227 auto viaToolActive =
228 [this]( const SELECTION& aSel )
229 {
230 return m_mode == MODE::VIA;
231 };
232
233 CONDITIONAL_MENU& ctxMenu = m_menu.GetMenu();
234
235 // cancel current tool goes in main context menu at the top if present
236 ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolFunctor, 1 );
237 ctxMenu.AddSeparator( 1 );
238
239 ctxMenu.AddItem( PCB_ACTIONS::clearHighlight, haveHighlight, 2 );
240 ctxMenu.AddSeparator( haveHighlight, 2 );
241
242 // tool-specific actions
243 ctxMenu.AddItem( PCB_ACTIONS::closeOutline, canCloseOutline, 200 );
244 ctxMenu.AddItem( PCB_ACTIONS::deleteLastPoint, canUndoPoint, 200 );
245 ctxMenu.AddItem( PCB_ACTIONS::arcPosture, arcToolActive, 200 );
246
248 ctxMenu.AddSeparator( 500 );
249
250 std::shared_ptr<VIA_SIZE_MENU> viaSizeMenu = std::make_shared<VIA_SIZE_MENU>();
251 viaSizeMenu->SetTool( this );
252 m_menu.RegisterSubMenu( viaSizeMenu );
253 ctxMenu.AddMenu( viaSizeMenu.get(), viaToolActive, 500 );
254
255 ctxMenu.AddSeparator( 500 );
256
257 // Type-specific sub-menus will be added for us by other tools
258 // For example, zone fill/unfill is provided by the PCB control tool
259
260 // Finally, add the standard zoom/grid items
261 getEditFrame<PCB_BASE_FRAME>()->AddStandardSubMenus( m_menu );
262
263 return true;
264}
static TOOL_ACTION cancelInteractive
Definition: actions.h:63
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 AddCheckItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a checked menu entry to run a TOOL_ACTION on selected items.
void AddMenu(ACTION_MENU *aMenu, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Add a submenu to the menu.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const std::set< int > & GetHighlightNetCodes() const
Return the netcode of currently highlighted net.
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:213
static TOOL_ACTION toggleHV45Mode
Definition: pcb_actions.h:466
static TOOL_ACTION clearHighlight
Definition: pcb_actions.h:496
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
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

References CONDITIONAL_MENU::AddCheckItem(), CONDITIONAL_MENU::AddItem(), CONDITIONAL_MENU::AddMenu(), CONDITIONAL_MENU::AddSeparator(), ARC, PCB_ACTIONS::arcPosture, ACTIONS::cancelInteractive, PCB_ACTIONS::clearHighlight, PCB_ACTIONS::closeOutline, PCB_ACTIONS::deleteLastPoint, KIGFX::RENDER_SETTINGS::GetHighlightNetCodes(), TOOL_MENU::GetMenu(), KIGFX::VIEW::GetPainter(), KIGFX::PAINTER::GetSettings(), TOOL_MANAGER::GetView(), GRAPHIC_POLYGON, KEEPOUT, TOOL_INTERACTIVE::m_menu, m_mode, TOOL_BASE::m_toolMgr, NONE, TOOL_MENU::RegisterSubMenu(), SELECTION_CONDITIONS::ShowAlways(), PCB_ACTIONS::toggleHV45Mode, VIA, and ZONE.

◆ InteractivePlaceWithPreview()

int DRAWING_TOOL::InteractivePlaceWithPreview ( const TOOL_EVENT aEvent,
std::vector< BOARD_ITEM * > &  aItems,
std::vector< BOARD_ITEM * > &  aPreview,
LSET aLayers 
)

Interactively place a set of BOARD_ITEM.

As a list of BOARD_ITEMs can be resource intesive to move around, we can use a reduced set of BOARD_ITEMs for preview purpose only.

Parameters
aEvent
aItemsBOARD_ITEMs to add to the board.
aPreviewBOARD_ITEMs only used during placement / preview.
aLayersSet of allowed destination when asking the user. If set to NULL, the user is not asked and all BOARD_ITEMs remain on their layers.

Definition at line 540 of file drawing_stackup_table_tool.cpp.

544{
546 return -1;
547
548 bool cancelled = false;
549
550 BOARD_COMMIT commit( m_frame );
551
553
554 // do not capture or auto-pan until we start placing the table
555 SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::TEXT );
556
557 m_frame->PushTool( aEvent );
558
559 Activate();
560 // Must be done after Activate() so that it gets set into the correct context
561 m_controls->ShowCursor( true );
562
563 if( aEvent.HasPosition() )
564 m_toolMgr->PrimeTool( aEvent.Position() );
565
566 // Main loop: keep receiving events
567 VECTOR2I cursorPosition;
568 VECTOR2I previousCursorPosition;
569
570 view()->ClearPreview();
571 view()->InitPreview();
572
573 for( BOARD_ITEM* item : aPreview )
574 {
575 item->Move( cursorPosition - previousCursorPosition );
576 view()->AddToPreview( item );
577 }
578
579 while( TOOL_EVENT* evt = Wait() )
580 {
582 cursorPosition = m_controls->GetCursorPosition();
583
584 if( evt->IsCancelInteractive() )
585 {
586 m_frame->PopTool( aEvent );
587 cancelled = true;
588 break;
589 }
590 else if( evt->IsMotion() )
591 {
592 view()->ShowPreview( false );
593
594 for( BOARD_ITEM* item : aPreview )
595 item->Move( cursorPosition - previousCursorPosition );
596
597 view()->ShowPreview( true );
598
599 previousCursorPosition = cursorPosition;
600 }
601 else if( evt->IsActivate() )
602 {
603 if( evt->IsMoveTool() )
604 {
605 // leave ourselves on the stack so we come back after the move
606 cancelled = true;
607 break;
608 }
609 else
610 {
611 m_frame->PopTool( aEvent );
612 cancelled = true;
613 break;
614 }
615 }
616 else if( evt->IsClick( BUT_RIGHT ) )
617 {
619 }
620 else if( evt->IsClick( BUT_LEFT ) )
621 {
622 if( aLayers != nullptr )
623 {
625 *aLayers, wxGetMousePosition() );
626
627 view()->ClearPreview();
628
629 if( destLayer == PCB_LAYER_ID::UNDEFINED_LAYER )
630 {
631 // The user did not pick any layer.
632 m_frame->PopTool( aEvent );
633 cancelled = true;
634 break;
635 }
636
637 for( BOARD_ITEM* item : aItems )
638 {
639 if( item->Type() == PCB_GROUP_T )
640 static_cast<PCB_GROUP*>( item )->SetLayerRecursive( destLayer, 200 );
641 else
642 item->SetLayer( destLayer );
643 }
644 }
645
646 for( BOARD_ITEM* item : aItems )
647 {
648 item->Move( cursorPosition );
649
650 if( item->Type() == PCB_GROUP_T )
651 static_cast<PCB_GROUP*>( item )->AddChildrenToCommit( commit );
652
653 commit.Add( item );
654 }
655
656 commit.Push( wxT( "Placing items" ) );
657 m_frame->PopTool( aEvent );
658
659 break;
660 }
661 // TODO: It'd be nice to be able to say "don't allow any non-trivial editing actions",
662 // but we don't at present have that, so we just knock out some of the egregious ones.
663 else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
664 {
665 wxBell();
666 }
667 else
668 {
669 evt->SetPassEvent();
670 }
671 }
672
673 view()->ClearPreview();
674 frame()->SetMsgPanel( board() );
675
676 if( cancelled )
677 return -1;
678
679 return 0;
680}
void ShowPreview(bool aShow=true)
Definition: view.cpp:1649
void AddToPreview(EDA_ITEM *aItem, bool aTakeOwnership=true)
Definition: view.cpp:1635
void InitPreview()
Definition: view.cpp:1628
void ClearPreview()
Definition: view.cpp:1613
PCB_LAYER_ID SelectOneLayer(PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask=LSET(), wxPoint aDlgPosition=wxDefaultPosition)
Show the dialog box for a layer selection.
Definition: sel_layer.cpp:274
A set of BOARD_ITEMs (i.e., without duplicates).
Definition: pcb_group.h:51
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition: pcb_group.h:122
void AddChildrenToCommit(BOARD_COMMIT &aCommit)
Add all the immediate children of this group to the board commit.
Definition: pcb_group.h:196
@ PCB_LAYER_ID_COUNT
Definition: layer_ids.h:137

References TOOL_INTERACTIVE::Activate(), COMMIT::Add(), PCB_GROUP::AddChildrenToCommit(), KIGFX::VIEW::AddToPreview(), PCB_TOOL_BASE::board(), BUT_LEFT, BUT_RIGHT, KIGFX::VIEW::ClearPreview(), PCB_TOOL_BASE::frame(), PCB_BASE_FRAME::GetCanvas(), KIGFX::VIEW_CONTROLS::GetCursorPosition(), PCB_BASE_FRAME::GetModel(), TOOL_EVENT::HasPosition(), KIGFX::VIEW::InitPreview(), ZONE_FILLER_TOOL::IsZoneFillAction(), m_controls, m_frame, PCB_TOOL_BASE::m_isFootprintEditor, TOOL_INTERACTIVE::m_menu, m_mode, TOOL_BASE::m_toolMgr, PCB_GROUP_T, PCB_LAYER_ID_COUNT, PENCIL, TOOLS_HOLDER::PopTool(), TOOL_EVENT::Position(), TOOL_MANAGER::PrimeTool(), BOARD_COMMIT::Push(), TOOLS_HOLDER::PushTool(), TOOL_MANAGER::RunAction(), PCB_TOOL_BASE::selection(), PCB_ACTIONS::selectionClear, PCB_BASE_FRAME::SelectOneLayer(), EDA_DRAW_PANEL_GAL::SetCurrentCursor(), PCB_GROUP::SetLayer(), EDA_DRAW_FRAME::SetMsgPanel(), TOOL_MENU::ShowContextMenu(), KIGFX::VIEW_CONTROLS::ShowCursor(), KIGFX::VIEW::ShowPreview(), TEXT, UNDEFINED_LAYER, PCB_TOOL_BASE::view(), and TOOL_INTERACTIVE::Wait().

Referenced by PlaceCharacteristics(), and PlaceStackup().

◆ 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,...
@ FRAME_PCB_EDITOR
Definition: frame_type.h:40
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 drawArc(), DrawDimension(), MICROWAVE_TOOL::drawMicrowaveInductor(), drawShape(), 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()

◆ 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 EDIT_TOOL::Drag(), ROUTER_TOOL::handleLayerSwitch(), PCB_SELECTION_TOOL::Main(), BOARD_EDITOR_CONTROL::TrackWidthDec(), and BOARD_EDITOR_CONTROL::TrackWidthInc().

◆ PlaceCharacteristics()

int DRAWING_TOOL::PlaceCharacteristics ( const TOOL_EVENT aEvent)

Definition at line 683 of file drawing_stackup_table_tool.cpp.

684{
685 VECTOR2I tableSize;
686
687 LSET layerSet = ( layerSet.AllCuMask() | layerSet.AllTechMask() );
688 layerSet = layerSet.set( Edge_Cuts ).set( Margin );
689 layerSet = layerSet.reset( F_Fab ).reset( B_Fab );
690
692
693 if( ( layerSet & LSET( layer ) ).count() ) // if layer is a forbidden layer
695
696 std::vector<BOARD_ITEM*> table = DrawBoardCharacteristics( { 0, 0 }, m_frame->GetActiveLayer(),
697 false, &tableSize );
698 std::vector<BOARD_ITEM*> preview;
699 std::vector<BOARD_ITEM*> items;
700
701 PCB_SHAPE* line1 = new PCB_SHAPE;
702 PCB_SHAPE* line2 = new PCB_SHAPE;
703 PCB_SHAPE* line3 = new PCB_SHAPE;
704 PCB_SHAPE* line4 = new PCB_SHAPE;
705
706 line1->SetStart( VECTOR2I( 0, 0 ) );
707 line1->SetEnd( VECTOR2I( tableSize.x, 0 ) );
708
709 line2->SetStart( VECTOR2I( 0, 0 ) );
710 line2->SetEnd( VECTOR2I( 0, tableSize.y ) );
711
712 line3->SetStart( VECTOR2I( tableSize.x, 0 ) );
713 line3->SetEnd( tableSize );
714
715 line4->SetStart( VECTOR2I( 0, tableSize.y ) );
716 line4->SetEnd( tableSize );
717
718 line1->SetLayer( m_frame->GetActiveLayer() );
719 line2->SetLayer( m_frame->GetActiveLayer() );
720 line3->SetLayer( m_frame->GetActiveLayer() );
721 line4->SetLayer( m_frame->GetActiveLayer() );
722
723 preview.push_back( line1 );
724 preview.push_back( line2 );
725 preview.push_back( line3 );
726 preview.push_back( line4 );
727
729 group->SetName("group-boardCharacteristics");
730
731 for( auto item : table )
732 group->AddItem( static_cast<BOARD_ITEM*>( item ) );
733
734 items.push_back( static_cast<BOARD_ITEM*>( group ) );
735
736 if( InteractivePlaceWithPreview( aEvent, items, preview, &layerSet ) == -1 )
737 m_frame->SetActiveLayer( layer );
738 else
739 m_frame->SetActiveLayer( table.front()->GetLayer() );
740
741 return 0;
742}
int InteractivePlaceWithPreview(const TOOL_EVENT &aEvent, std::vector< BOARD_ITEM * > &aItems, std::vector< BOARD_ITEM * > &aPreview, LSET *aLayers)
Interactively place a set of BOARD_ITEM.
std::vector< BOARD_ITEM * > DrawBoardCharacteristics(const VECTOR2I &origin, PCB_LAYER_ID aLayer, bool aDrawNow, VECTOR2I *tablesize)
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:124
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:149
static LSET AllTechMask()
Return a mask holding all technical layers (no CU layer) on both side.
Definition: lset.cpp:841
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:773
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
@ Edge_Cuts
Definition: layer_ids.h:113
@ Cmts_User
Definition: layer_ids.h:110
@ F_Fab
Definition: layer_ids.h:120
@ Margin
Definition: layer_ids.h:114
@ B_Fab
Definition: layer_ids.h:119

References LSET::AllCuMask(), LSET::AllTechMask(), B_Fab, Cmts_User, DrawBoardCharacteristics(), Edge_Cuts, F_Fab, PCB_BASE_FRAME::GetActiveLayer(), group, InteractivePlaceWithPreview(), m_board, m_frame, Margin, PCB_BASE_FRAME::SetActiveLayer(), EDA_SHAPE::SetEnd(), BOARD_ITEM::SetLayer(), EDA_SHAPE::SetStart(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by setTransitions().

◆ PlaceImage()

int DRAWING_TOOL::PlaceImage ( const TOOL_EVENT aEvent)

Display a dialog that allows one to select and image then decide where to place the image in the editor.

Definition at line 533 of file drawing_tool.cpp.

534{
535 if( m_inDrawingTool )
536 return 0;
537
539
540 PCB_BITMAP* image = aEvent.Parameter<PCB_BITMAP*>();
541 bool immediateMode = image != nullptr;
543 bool ignorePrimePosition = false;
544 COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
545
548 BOARD_COMMIT commit( m_frame );
549
551
552 // Add all the drawable symbols to preview
553 if( image )
554 {
555 image->SetPosition( cursorPos );
557 m_view->AddToPreview( image, false ); // Add, but not give ownership
558 }
559
560 m_frame->PushTool( aEvent );
561 auto setCursor =
562 [&]()
563 {
564 if( image )
566 else
568 };
569
570 auto cleanup =
571 [&] ()
572 {
576 delete image;
577 image = nullptr;
578 };
579
580 Activate();
581
582 // Must be done after Activate() so that it gets set into the correct context
583 getViewControls()->ShowCursor( true );
584
585 // Set initial cursor
586 setCursor();
587
588 // Prime the pump
589 if( image )
590 {
592 }
593 else if( aEvent.HasPosition() )
594 {
595 m_toolMgr->PrimeTool( aEvent.