52#define QUIET_MODE true
57 m_inMoveTool( false ),
58 m_moveInProgress( false ),
107 bool foundAttachment =
false;
108 bool foundJunction =
false;
109 bool foundPin =
false;
114 foundAttachment =
true;
118 switch( cItem->Type() )
134 if( !foundLine && cLine->
GetLength() == 0 )
140 foundJunction =
true;
150 if( pair.first->IsConnected( selectedEnd ) )
170 bool preferOriginalLine =
false;
174 && line->GetLength() == 0
177 preferOriginalLine =
true;
183 else if( !foundLine && foundJunction && !foundPin )
186 foundLine =
new SCH_LINE( unselectedEnd, line->GetLayer() );
202 if( foundLine && !preferOriginalLine )
223 else if( foundLine->
GetEndPoint() == unselectedEnd )
224 foundLine->
MoveEnd( splitDelta );
280 line->MoveStart( splitDelta );
285 else if( line->GetLength() == 0 )
295 else if( foundAttachment && line->IsOrthogonal() )
302 unsigned int xMoveBit = splitDelta.
x != 0;
303 unsigned int yMoveBit = splitDelta.
y != 0;
304 int xLength = abs( unselectedEnd.
x - selectedEnd.
x );
305 int yLength = abs( unselectedEnd.
y - selectedEnd.
y );
306 int xMove = ( xLength - ( xBendCount * lineGrid.
x ) )
307 *
sign( selectedEnd.
x - unselectedEnd.
x );
308 int yMove = ( yLength - ( yBendCount * lineGrid.
y ) )
309 *
sign( selectedEnd.
y - unselectedEnd.
y );
329 xBendCount += yMoveBit;
330 yBendCount += xMoveBit;
335 line->MoveEnd(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
336 splitDelta.
y ? splitDelta.
y : yMove ) );
340 line->MoveStart(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
341 splitDelta.
y ? splitDelta.
y : yMove ) );
362 else if( !foundAttachment )
365 line->MoveEnd( splitDelta );
367 line->MoveStart( splitDelta );
379 bool isSlice =
false;
422 if( sel && !sel->
IsNew() )
431 controls->SetAutoPan(
false );
455 if( userSelection.
GetSize() == 1 )
475 bool unselect = selection.
IsHover();
478 std::vector<DANGLING_END_ITEM> internalPoints;
483 controls->ShowCursor(
true );
487 if( selection.
Empty() )
495 bool restore_state =
false;
501 m_cursor = controls->GetCursorPosition();
520 bool placingNewItems = sch_item && sch_item->
IsNew();
528 internalPoints.clear();
535 if( !it->IsSelected() )
548 std::vector<SCH_ITEM*> stageTwo;
550 for(
EDA_ITEM* edaItem : selection )
553 std::vector<VECTOR2I> connections;
555 switch( item->
Type() )
561 stageTwo.emplace_back(item);
565 static_cast<SCH_LINE*
>( item )->GetSelectedPoints( connections );
571 for(
const VECTOR2I& point : connections )
579 for(
const VECTOR2I& point : item->GetConnectionPoints() )
583 for(
EDA_ITEM* item : connectedDragItems )
591 for(
EDA_ITEM* edaItem : selection )
612 static_cast<SCH_ITEM*
>( item )->GetEndPoints( internalPoints );
614 std::vector<DANGLING_END_ITEM> endPointsByType = internalPoints;
615 std::vector<DANGLING_END_ITEM> endPointsByPos = endPointsByType;
619 static_cast<SCH_ITEM*
>( item )->UpdateDanglingState( endPointsByType, endPointsByPos );
624 snapLayer =
grid.GetSelectionGrid( selection );
632 else if( item->GetParent() && item->GetParent()->IsSelected() )
645 shape->SetHatchingDirty();
646 shape->UpdateHatching();
649 static_cast<SCH_ITEM*
>( item )->RunOnChildren(
654 RECURSE_MODE::RECURSE );
662 m_cursor = controls->GetCursorPosition();
666 wxASSERT_MSG(
m_anchorPos,
"Should be already set from previous cmd" );
668 else if( placingNewItems )
676 bool isPasted =
false;
682 if( item->GetParent() && item->GetParent()->IsSelected() )
688 isPasted |= ( item->GetFlags() &
IS_PASTED ) != 0;
696 selection.SetReferencePoint(
m_cursor );
713 selection.SetReferencePoint(
m_cursor );
722 controls->SetCursorPosition(
m_cursor,
false );
725 controls->SetAutoPan(
true );
732 m_cursor =
grid.BestSnapAnchor( controls->GetCursorPosition(
false ),
733 snapLayer, selection );
743 std::vector<VECTOR2I> splitMoves;
774 for(
const VECTOR2I& splitDelta : splitMoves )
777 if( splitDelta ==
VECTOR2I( 0, 0 ) )
784 if( item->GetParent() && item->GetParent()->IsSelected() )
809 if( lineEnd.second && lineEnd.first->HasFlag(
STARTPOINT ) )
810 lineEnd.first->SetStartPoint(
pin->GetPosition() );
811 else if( !lineEnd.second && lineEnd.first->HasFlag(
ENDPOINT ) )
812 lineEnd.first->SetEndPoint(
pin->GetPosition() );
848 restore_state =
true;
941 }
while( ( evt =
Wait() ) );
949 selectionCopy.
Add( line );
952 selectionCopy.
Add( line );
957 newLine->ClearEditFlags();
964 oldLine->ClearEditFlags();
969 controls->ForceCursorPosition(
false );
970 controls->ShowCursor(
false );
971 controls->SetAutoPan(
false );
988 sch_item->SetConnectivityDirty(
true );
991 if( selection.GetSize() == 1 && selection.Front()->IsNew() )
1021 item->ClearEditFlags();
1025 for(
EDA_ITEM* item : selectionCopy )
1026 item->ClearEditFlags();
1038 return !restore_state;
1047 std::set<SCH_ITEM*> danglers;
1049 std::function<void(
SCH_ITEM* )> changeHandler =
1050 [&](
SCH_ITEM* aChangedItem ) ->
void
1057 if( aChangedItem->HasFlag(
IS_BROKEN) && aChangedItem->IsDangling()
1058 && !aChangedItem->IsSelected() )
1060 danglers.insert( aChangedItem );
1090 for(
SCH_ITEM* item : itemsOverlapping )
1092 if( item != aOriginalItem && item->
IsConnected( aPoint ) )
1095 foundJunction = item;
1101 if( foundSymbol && foundJunction )
1103 aList.push_back( foundSymbol );
1109 aList.push_back( foundJunction );
1116 if(
test == aOriginalItem || !
test->CanConnect( aOriginalItem ) )
1119 switch(
test->Type() )
1135 if(
test->IsConnected( aPoint ) )
1136 aList.push_back(
test );
1142 aList.push_back(
test );
1155 if(
pin->IsConnected( aPoint ) )
1157 if(
pin->IsSelected() )
1161 aList.push_back(
pin );
1171 if(
test->IsConnected( aPoint ) )
1172 aList.push_back(
test );
1187 aList.push_back( label );
1199 if( line->
HitTest( aPoint, 1 ) )
1200 aList.push_back( label );
1217 std::vector<SCH_ITEM*> itemsConnectable;
1218 bool ptHasUnselectedJunction =
false;
1241 if(
dynamic_cast<const SCH_LINE*
>( selected ) )
1243 else if(
dynamic_cast<const SCH_LINE*
>( fixed ) )
1253 auto makeNewJunction =
1270 for(
SCH_ITEM* item : itemsOverlappingRTree )
1279 &&
pin->CanConnect( aSelectedItem ) )
1281 itemsConnectable.push_back(
pin );
1290 if( item == aSelectedItem || ( item->Type() !=
SCH_LINE_T && item->IsSelected() )
1296 itemsConnectable.push_back( item );
1299 for(
SCH_ITEM* item : itemsConnectable )
1301 if( item->Type() ==
SCH_JUNCTION_T && item->IsConnected( aPoint ) && !item->IsSelected() )
1303 ptHasUnselectedJunction =
true;
1320 if( ptHasUnselectedJunction )
1340 aList.push_back( line );
1354 aList.push_back( line );
1359 switch( aSelectedItem->
Type() )
1373 newWire = makeNewWire( aCommit, line, aSelectedItem, aPoint, aPoint );
1376 aList.push_back( newWire );
1381 if( !line->
IsNew() )
1387 makeNewWire( aCommit, line, line, aPoint, oldEnd );
1388 makeNewJunction( aCommit, line, aPoint );
1420 aList.push_back( label );
1423 info.attachedLine = line;
1435 if(
pin->IsConnected( aPoint ) )
1446 newWire = makeNewWire( aCommit,
pin, aSelectedItem, aPoint, aPoint );
1448 aList.push_back( newWire );
1457 if(
test->IsConnected( aPoint ) && !newWire )
1461 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1463 aList.push_back( newWire );
1472 aList.push_back(
test );
1509 aList.push_back( label );
1514 info.attachedLine = line;
1521 else if(
test->IsConnected( aPoint ) && !newWire )
1525 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1527 aList.push_back( newWire );
1553 if( line->
HitTest( point, 1 ) )
1556 aList.push_back(
test );
1559 std::vector<VECTOR2I> ends =
test->GetConnectionPoints();
1562 if( ends[0] == point )
1586 switch( aItem->
Type() )
1628 pin->SetStoredPos(
pin->GetStoredPos() + aDelta );
1629 pin->ConstrainOnEdge(
pin->GetStoredPos(), true );
1643 SEG currentLine(
info.attachedLine->GetStartPoint(),
info.attachedLine->GetEndPoint() );
1648 label->
Move( aDelta );
1655 static_cast<SCH_ITEM*
>( aItem )->Move( aDelta );
1688 if( !it->IsSelected() )
1691 if( !selection.
IsHover() && it->IsSelected() )
1694 it->SetStoredPos( it->GetPosition() );
1699 pin->SetStoredPos(
pin->GetPosition() );
1711 for(
int ii = 0; ii < 2; ++ii )
1718 std::set<EDA_ITEM*> unique_items( drag_items.begin(), drag_items.end() );
1724 for(
EDA_ITEM* dragItem : unique_items )
1726 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1729 doMoveItem( dragItem,
delta );
1739 doMoveItem( item,
delta );
1746 VECTOR2I tl_delta =
grid.AlignGrid( topLeft, selectionGrid ) - topLeft;
1747 VECTOR2I br_delta =
grid.AlignGrid( bottomRight, selectionGrid ) - bottomRight;
1751 doMoveItem( sheet, tl_delta );
1762 if(
pin->GetSide() == SHEET_SIDE::TOP ||
pin->GetSide() == SHEET_SIDE::LEFT )
1763 newPos =
pin->GetPosition() + tl_delta;
1765 newPos =
pin->GetPosition() + br_delta;
1777 for(
EDA_ITEM* dragItem : drag_items )
1779 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1782 doMoveItem( dragItem,
delta );
1793 for(
const VECTOR2I& point : connections )
1796 std::map<VECTOR2I, int> shifts;
1800 for(
const VECTOR2I& conn : connections )
1802 VECTOR2I gridpt =
grid.AlignGrid( conn, selectionGrid ) - conn;
1806 if( shifts[gridpt] > max_count )
1808 most_common = gridpt;
1809 max_count = shifts[most_common];
1813 if( most_common !=
VECTOR2I( 0, 0 ) )
1815 doMoveItem( item, most_common );
1817 for(
EDA_ITEM* dragItem : drag_items )
1819 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1822 doMoveItem( dragItem, most_common );
1835 commit.
Push(
_(
"Align Items to Grid" ) );
static TOOL_ACTION duplicate
static TOOL_ACTION doDelete
static TOOL_ACTION cursorClick
static TOOL_ACTION increment
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION refreshPreview
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
COMMIT & Removed(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
static void sort_dangling_end_items(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos)
Both contain the same information.
Helper class used to store the state of schematic items that can be connected to other schematic item...
bool IsParallelTo(EDA_ANGLE aAngle) const
void ShowInfoBarMsg(const wxString &aMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an info icon on the left of...
WX_INFOBAR * GetInfoBar()
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
EDA_ITEM * GetParent() const
bool HasFlag(EDA_ITEM_FLAGS aFlag) const
const VECTOR2I & GetTextPos() const
Implement an R-tree for fast spatial and type indexing of schematic items.
EE_TYPE Overlapping(const BOX2I &aRect) const
static const TOOL_EVENT SelectedItemsMoved
Used to inform tools that the selection should temporarily be non-editable.
An interface for classes handling user events controlling the view behavior such as zooming,...
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual 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...
virtual SETTINGS_MANAGER & GetSettingsManager() const
static TOOL_ACTION rotateCCW
static TOOL_ACTION restartMove
static TOOL_ACTION rotateCW
static TOOL_ACTION alignToGrid
static TOOL_ACTION highlightNet
static TOOL_ACTION selectOnPCB
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen=nullptr)
Add an item to the screen (and view) aScreen is the screen the item is located on,...
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Remove an item from the screen (and view) aScreen is the screen the item is located on,...
static const std::vector< KICAD_T > MovableItems
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
virtual void Revert() override
Revert the commit by restoring the modified items state.
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SchematicCleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
void FlipBodyStyle(SCH_SYMBOL *aSymbol)
void SelectUnit(SCH_SYMBOL *aSymbol, int aUnit)
void AutoRotateItem(SCH_SCREEN *aScreen, SCH_ITEM *aItem)
Automatically set the rotation of an item (if the item supports it).
SCH_JUNCTION * AddJunction(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen, const VECTOR2I &aPos)
void SaveCopyForRepeatItem(const SCH_ITEM *aItem)
Clone aItem and owns that clone in this container.
Base class for any item which can be embedded within the SCHEMATIC container class,...
void SetStoredPos(const VECTOR2I &aPos)
virtual bool CanConnect(const SCH_ITEM *aItem) const
void SetLayer(SCH_LAYER_ID aLayer)
void SetConnectivityDirty(bool aDirty=true)
void SetFieldsAutoplaced(AUTOPLACE_ALGO aAlgo)
bool IsConnected(const VECTOR2I &aPoint) const
Test the item to see if it is connected to aPoint.
virtual bool IsMovableFromAnchorPoint() const
Check if object is movable from the anchor point.
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
void SetLastResolvedState(const SCH_ITEM *aItem) override
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
void SetPosition(const VECTOR2I &aPosition) override
bool CanConnect(const SCH_ITEM *aItem) const override
Segment description base class to describe items which have 2 end points (track, wire,...
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
void StoreAngle()
Save the current line angle.
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
EDA_ANGLE Angle() const
Get the angle between the start and end lines.
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
void MoveEnd(const VECTOR2I &aMoveVector)
void SetLastResolvedState(const SCH_ITEM *aItem) override
void MoveStart(const VECTOR2I &aMoveVector)
void SetEndPoint(const VECTOR2I &aPosition)
void TestDanglingEnds(const SCH_SHEET_PATH *aPath=nullptr, std::function< void(SCH_ITEM *)> *aChangedHandler=nullptr) const
Test all of the connectable objects in the schematic for unused connection points.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
bool IsExplicitJunctionNeeded(const VECTOR2I &aPosition) const
Indicate that a junction dot is necessary at the given location, and does not yet exist.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetSize(const VECTOR2I &aSize)
VECTOR2I GetPosition() const override
std::vector< SCH_SHEET_PIN * > & GetPins()
VECTOR2I GetPosition() const override
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
virtual void Add(EDA_ITEM *aItem)
VECTOR2I GetReferencePoint() const
virtual unsigned int GetSize() const override
Return the number of stored items.
void SetReferencePoint(const VECTOR2I &aP)
bool Empty() const
Checks if there is anything selected.
std::vector< EDA_ITEM * > GetItemsSortedByTypeAndXY(bool leftBeforeRight=true, bool topBeforeBottom=true) const
Returns a copy of this selection of items sorted by their X then Y position.
bool HasReferencePoint() const
T * GetAppSettings(const char *aFilename)
Return a handle to the a given settings by type.
const TRANSFORM & GetTransform() const
void Dismiss() override
Dismisses the infobar and updates the containing layout and AUI manager (if one is provided).
static constexpr EDA_ANGLE ANGLE_90
std::vector< EDA_ITEM * > EDA_ITEMS
Define list of drawing items for screens.
#define IS_PASTED
Modifier on IS_NEW which indicates it came from clipboard.
#define IS_CHANGED
Item was edited, and modified.
#define IS_NEW
New item, just created.
#define SELECTED
Item was manually selected by the user.
#define SELECTED_BY_DRAG
Item was algorithmically selected as a dragged item.
#define IS_BROKEN
Is a segment just broken by BreakSegment.
#define STRUCT_DELETED
flag indication structures to be erased
#define ENDPOINT
ends. (Used to support dragging.)
#define IS_MOVING
Item being moved.
#define STARTPOINT
When a line is selected, these flags indicate which.
@ ID_POPUP_SCH_SELECT_UNIT
@ ID_POPUP_SCH_SELECT_BASE
@ ID_POPUP_SCH_SELECT_ALT
@ ID_POPUP_SCH_SELECT_UNIT_END
@ REPAINT
Item needs to be redrawn.
bool signbit(T v)
Integral version of std::signbit that works all compilers.
PGM_BASE & Pgm()
The global program "get" accessor.
Class to handle a set of SCH_ITEMs.
The EE_TYPE struct provides a type-specific auto-range iterator to the RTree.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
constexpr int sign(T val)
VECTOR2< int32_t > VECTOR2I