56#define QUIET_MODE true
111 bool foundAttachment =
false;
112 bool foundJunction =
false;
113 bool foundPin =
false;
118 foundAttachment =
true;
122 switch( cItem->Type() )
138 if( !foundLine && cLine->
GetLength() == 0 )
144 foundJunction =
true;
154 if( pair.first->IsConnected( selectedEnd ) )
174 bool preferOriginalLine =
false;
178 && line->GetLength() == 0
179 &&
EDA_ANGLE( splitDelta ).IsParallelTo( line->GetStoredAngle() ) )
181 preferOriginalLine =
true;
187 else if( !foundLine && foundJunction && !foundPin )
190 foundLine =
new SCH_LINE( unselectedEnd, line->GetLayer() );
206 if( foundLine && !preferOriginalLine )
227 else if( foundLine->
GetEndPoint() == unselectedEnd )
228 foundLine->
MoveEnd( splitDelta );
282 line->MoveEnd( splitDelta );
284 line->MoveStart( splitDelta );
289 else if( line->GetLength() == 0 )
299 else if( foundAttachment && line->IsOrthogonal() )
306 unsigned int xMoveBit = splitDelta.
x != 0;
307 unsigned int yMoveBit = splitDelta.
y != 0;
308 int xLength = abs( unselectedEnd.
x - selectedEnd.
x );
309 int yLength = abs( unselectedEnd.
y - selectedEnd.
y );
310 int xMove = ( xLength - ( xBendCount * lineGrid.
x ) )
311 *
sign( selectedEnd.
x - unselectedEnd.
x );
312 int yMove = ( yLength - ( yBendCount * lineGrid.
y ) )
313 *
sign( selectedEnd.
y - unselectedEnd.
y );
333 xBendCount += yMoveBit;
334 yBendCount += xMoveBit;
339 line->MoveEnd(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
340 splitDelta.
y ? splitDelta.
y : yMove ) );
344 line->MoveStart(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
345 splitDelta.
y ? splitDelta.
y : yMove ) );
366 else if( !foundAttachment )
369 line->MoveEnd( splitDelta );
371 line->MoveStart( splitDelta );
383 bool isSlice =
false;
415 bool isLineModeConstrained =
false;
428 if( sel && !sel->
IsNew() )
461 if( userSelection.
GetSize() == 1 )
481 bool unselect = selection.
IsHover();
484 std::vector<DANGLING_END_ITEM> internalPoints;
493 if( selection.
Empty() )
501 bool restore_state =
false;
527 bool placingNewItems = sch_item && sch_item->
IsNew();
535 internalPoints.clear();
542 if( !it->IsSelected() )
555 std::vector<SCH_ITEM*> stageTwo;
557 for(
EDA_ITEM* edaItem : selection )
560 std::vector<VECTOR2I> connections;
562 switch( item->
Type() )
568 stageTwo.emplace_back(item);
572 static_cast<SCH_LINE*
>( item )->GetSelectedPoints( connections );
578 for(
const VECTOR2I& point : connections )
586 for(
const VECTOR2I& point : item->GetConnectionPoints() )
590 for(
EDA_ITEM* item : connectedDragItems )
598 for(
EDA_ITEM* edaItem : selection )
619 static_cast<SCH_ITEM*
>( item )->GetEndPoints( internalPoints );
621 std::vector<DANGLING_END_ITEM> endPointsByType = internalPoints;
622 std::vector<DANGLING_END_ITEM> endPointsByPos = endPointsByType;
626 static_cast<SCH_ITEM*
>( item )->UpdateDanglingState( endPointsByType, endPointsByPos );
632 for(
EDA_ITEM* edaItem : selection )
654 snapLayer =
grid.GetSelectionGrid( selection );
660 if( schItem->
IsNew() )
671 enteredGroup->AddItem( schItem );
688 shape->SetHatchingDirty();
689 shape->UpdateHatching();
708 wxASSERT_MSG(
m_anchorPos,
"Should be already set from previous cmd" );
710 else if( placingNewItems )
718 bool isPasted =
false;
724 if( item->GetParent() && item->GetParent()->IsSelected() )
730 isPasted |= ( item->GetFlags() &
IS_PASTED ) != 0;
738 selection.SetReferencePoint(
m_cursor );
751 if(
m_frame->GetMoveWarpsCursor() )
755 selection.SetReferencePoint(
m_cursor );
777 snapLayer, selection );
791 selBBox.
Merge( schIt->GetBoundingBox() );
818 if( sheet != hoverSheet )
823 m_frame->UpdateItem( hoverSheet,
false );
831 m_frame->UpdateItem( hoverSheet,
false );
845 std::vector<VECTOR2I> splitMoves;
876 for(
const VECTOR2I& splitDelta : splitMoves )
879 if( splitDelta ==
VECTOR2I( 0, 0 ) )
886 if( item->GetParent() && item->GetParent()->IsSelected() )
893 if(
m_isDrag && isLineModeConstrained
909 if( lineEnd.second && lineEnd.first->HasFlag(
STARTPOINT ) )
910 lineEnd.first->SetStartPoint(
pin->GetPosition() );
911 else if( !lineEnd.second && lineEnd.first->HasFlag(
ENDPOINT ) )
912 lineEnd.first->SetEndPoint(
pin->GetPosition() );
920 std::vector<SCH_ITEM*> previewItems;
923 previewItems.push_back(
static_cast<SCH_ITEM*
>( it ) );
926 previewItems.push_back( line );
929 previewItems.push_back( line );
934 m_view->AddToPreview( jct,
true );
948 m_frame->GetInfoBar()->Dismiss();
958 m_frame->ShowInfoBarMsg(
_(
"Press <ESC> to cancel drag." ) );
960 m_frame->ShowInfoBarMsg(
_(
"Press <ESC> to cancel move." ) );
967 restore_state =
true;
1050 m_frame->SelectUnit( symbol, unit );
1062 m_frame->SelectBodyStyle( symbol, bodyStyle );
1095 }
while( ( evt =
Wait() ) );
1102 m_frame->UpdateItem( hoverSheet,
false );
1119 selectionCopy.
Add( line );
1122 selectionCopy.
Add( line );
1127 newLine->ClearEditFlags();
1134 oldLine->ClearEditFlags();
1158 sch_item->SetConnectivityDirty(
true );
1161 if( selection.GetSize() == 1 && selection.Front()->IsNew() )
1162 m_frame->SaveCopyForRepeatItem(
static_cast<SCH_ITEM*
>( selection.Front() ) );
1172 if(
m_frame->GetScreen()->IsExplicitJunctionNeeded( it.GetPosition()) )
1188 m_frame->Schematic().CleanUp( aCommit );
1192 item->ClearEditFlags();
1196 for(
EDA_ITEM* item : selectionCopy )
1197 item->ClearEditFlags();
1212 return !restore_state;
1225 bbox.
Merge(
static_cast<SCH_ITEM*
>( item )->GetBoundingBox() );
1229 bool overlap =
false;
1234 moved.Move( offset );
1239 if(
moved.Intersects( existing->GetBoundingBox() ) )
1255 m_frame->RemoveFromScreen( schItem, srcScreen );
1258 schItem->
Move( offset );
1261 destScreen->
Append( schItem );
1275 std::set<SCH_ITEM*> danglers;
1277 std::function<void(
SCH_ITEM* )> changeHandler =
1278 [&](
SCH_ITEM* aChangedItem ) ->
void
1285 if( aChangedItem->HasFlag(
IS_BROKEN) && aChangedItem->IsDangling()
1286 && !aChangedItem->IsSelected() )
1288 danglers.insert( aChangedItem );
1292 m_frame->GetScreen()->TestDanglingEnds(
nullptr, &changeHandler );
1317 for(
SCH_ITEM* item : itemsOverlapping )
1319 if( item != aOriginalItem && item->
IsConnected( aPoint ) )
1322 foundJunction = item;
1328 if( foundSymbol && foundJunction )
1330 aList.push_back( foundSymbol );
1336 aList.push_back( foundJunction );
1343 if(
test == aOriginalItem || !
test->CanConnect( aOriginalItem ) )
1346 switch(
test->Type() )
1362 if(
test->IsConnected( aPoint ) )
1363 aList.push_back(
test );
1368 if(
static_cast<SCH_LINE*
>(
test )->HitTest( label->GetPosition(), 1 ) )
1369 aList.push_back(
test );
1382 if(
pin->IsConnected( aPoint ) )
1384 if(
pin->IsSelected() )
1387 aList.push_back(
pin );
1397 if(
test->IsConnected( aPoint ) )
1398 aList.push_back(
test );
1413 aList.push_back( label );
1425 if( line->
HitTest( aPoint, 1 ) )
1426 aList.push_back( label );
1443 std::vector<SCH_ITEM*> itemsConnectable;
1444 bool ptHasUnselectedJunction =
false;
1467 if(
dynamic_cast<const SCH_LINE*
>( selected ) )
1469 else if(
dynamic_cast<const SCH_LINE*
>( fixed ) )
1479 auto makeNewJunction =
1496 for(
SCH_ITEM* item : itemsOverlappingRTree )
1504 if( !
pin->IsSelected()
1506 &&
pin->CanConnect( aSelectedItem ) )
1508 itemsConnectable.push_back(
pin );
1517 if( item == aSelectedItem
1518 || ( item->Type() !=
SCH_LINE_T && item->IsSelected() )
1524 itemsConnectable.push_back( item );
1527 for(
SCH_ITEM* item : itemsConnectable )
1529 if( item->Type() ==
SCH_JUNCTION_T && item->IsConnected( aPoint ) && !item->IsSelected() )
1531 ptHasUnselectedJunction =
true;
1548 if( ptHasUnselectedJunction )
1568 aList.push_back( line );
1582 aList.push_back( line );
1587 switch( aSelectedItem->
Type() )
1601 newWire = makeNewWire( aCommit, line, aSelectedItem, aPoint, aPoint );
1604 aList.push_back( newWire );
1614 makeNewWire( aCommit, line, line, aPoint, oldEnd );
1615 makeNewJunction( aCommit, line, aPoint );
1647 aList.push_back( label );
1650 info.attachedLine = line;
1662 if(
pin->IsConnected( aPoint ) )
1673 newWire = makeNewWire( aCommit,
pin, aSelectedItem, aPoint, aPoint );
1675 aList.push_back( newWire );
1684 if(
test->IsConnected( aPoint ) && !newWire )
1688 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1690 aList.push_back( newWire );
1699 aList.push_back(
test );
1734 aList.push_back( label );
1739 info.attachedLine = line;
1746 else if(
test->IsConnected( aPoint ) && !newWire )
1750 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1752 aList.push_back( newWire );
1778 if( line->
HitTest( point, 1 ) )
1781 aList.push_back(
test );
1784 std::vector<VECTOR2I> ends =
test->GetConnectionPoints();
1787 if( ends[0] == point )
1811 switch( aItem->
Type() )
1853 pin->SetStoredPos(
pin->GetStoredPos() + aDelta );
1854 pin->ConstrainOnEdge(
pin->GetStoredPos(),
true );
1868 SEG currentLine(
info.attachedLine->GetStartPoint(),
info.attachedLine->GetEndPoint() );
1873 label->
Move( aDelta );
1880 static_cast<SCH_ITEM*
>( aItem )->Move( aDelta );
1913 if( !it->IsSelected() )
1916 if( !selection.
IsHover() && it->IsSelected() )
1919 it->SetStoredPos( it->GetPosition() );
1924 pin->SetStoredPos(
pin->GetPosition() );
1936 for(
int ii = 0; ii < 2; ++ii )
1943 std::set<EDA_ITEM*> unique_items( drag_items.begin(), drag_items.end() );
1949 for(
EDA_ITEM* dragItem : unique_items )
1951 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1954 doMoveItem( dragItem,
delta );
1964 doMoveItem( item,
delta );
1971 VECTOR2I tl_delta =
grid.AlignGrid( topLeft, selectionGrid ) - topLeft;
1972 VECTOR2I br_delta =
grid.AlignGrid( bottomRight, selectionGrid ) - bottomRight;
1976 doMoveItem( sheet, tl_delta );
1988 newPos =
pin->GetPosition() + tl_delta;
1990 newPos =
pin->GetPosition() + br_delta;
2002 for(
EDA_ITEM* dragItem : drag_items )
2004 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
2007 doMoveItem( dragItem,
delta );
2018 for(
const VECTOR2I& point : connections )
2021 std::map<VECTOR2I, int> shifts;
2025 for(
const VECTOR2I& conn : connections )
2027 VECTOR2I gridpt =
grid.AlignGrid( conn, selectionGrid ) - conn;
2031 if( shifts[gridpt] > max_count )
2033 most_common = gridpt;
2034 max_count = shifts[most_common];
2038 if( most_common !=
VECTOR2I( 0, 0 ) )
2040 doMoveItem( item, most_common );
2042 for(
EDA_ITEM* dragItem : drag_items )
2044 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
2047 doMoveItem( dragItem, most_common );
2059 m_frame->Schematic().CleanUp( &commit );
2060 commit.
Push(
_(
"Align Items to Grid" ) );
constexpr EDA_IU_SCALE schIUScale
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
constexpr const Vec & GetPosition() const
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr coord_type GetX() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr size_type GetHeight() const
constexpr bool Contains(const Vec &aPoint) const
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
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...
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)
virtual EDA_GROUP * GetParentGroup() const
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,...
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.
VECTOR2D GetCursorPosition() const
Return the current cursor position in world coordinates.
virtual void SetCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true, bool aTriggeredByArrows=false, long aArrowCommand=0)=0
Move cursor to the requested position expressed in world coordinates.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
static TOOL_ACTION rotateCCW
static TOOL_ACTION toText
static TOOL_ACTION restartMove
static TOOL_ACTION toHLabel
static TOOL_ACTION rotateCW
static TOOL_ACTION toLabel
static TOOL_ACTION alignToGrid
static TOOL_ACTION toDLabel
static TOOL_ACTION toTextBox
static TOOL_ACTION highlightNet
static TOOL_ACTION repeatDrawItem
static TOOL_ACTION toGLabel
static TOOL_ACTION selectOnPCB
static const std::vector< KICAD_T > MovableItems
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE) override
Add a change of the item aItem of type aChangeType to the change list.
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.
A set of SCH_ITEMs (i.e., without duplicates).
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
virtual void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction, RECURSE_MODE aMode)
virtual void Move(const VECTOR2I &aMoveVector)
Move the item by aMoveVector to a new position.
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.
bool IsGroupableType() const
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 Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
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)
SCH_SCREEN * GetScreen() const
VECTOR2I GetPosition() const override
const BOX2I GetBodyBoundingBox() const
Return a bounding box for the sheet body but not the fields.
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
const TRANSFORM & GetTransform() const
@ CHT_DONE
Flag to indicate the change is already applied.
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 BRIGHTENED
item is drawn with a bright contour
#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_BODY_STYLE
@ ID_POPUP_SCH_SELECT_BODY_STYLE_END
@ ID_POPUP_SCH_SELECT_UNIT_END
std::vector< SCH_JUNCTION * > PreviewJunctions(const class SCH_SCREEN *aScreen, const std::vector< class SCH_ITEM * > &aItems)
Determine the points where explicit junctions would be required if the given temporary items were com...
@ REPAINT
Item needs to be redrawn.
bool signbit(T v)
Integral version of std::signbit that works all compilers.
Class to handle a set of SCH_ITEMs.
T * GetAppSettings(const char *aFilename)
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
VECTOR2< double > VECTOR2D