47#define QUIET_MODE true
52 m_inMoveTool( false ),
53 m_moveInProgress( false ),
102 bool foundAttachment =
false;
103 bool foundJunction =
false;
104 bool foundPin =
false;
109 foundAttachment =
true;
113 switch( cItem->Type() )
129 if( !foundLine && cLine->
GetLength() == 0 )
135 foundJunction =
true;
153 bool preferOriginalLine =
false;
157 && line->GetLength() == 0
160 preferOriginalLine =
true;
166 else if( !foundLine && foundJunction && !foundPin )
169 foundLine =
new SCH_LINE( unselectedEnd, line->GetLayer() );
185 if( foundLine && !preferOriginalLine )
205 else if( foundLine->
GetEndPoint() == unselectedEnd )
206 foundLine->
MoveEnd( splitDelta );
263 line->MoveStart( splitDelta );
268 else if( line->GetLength() == 0 )
278 else if( foundAttachment && line->IsOrthogonal() )
283 unsigned int xMoveBit = splitDelta.
x != 0;
284 unsigned int yMoveBit = splitDelta.
y != 0;
285 int xLength =
abs( unselectedEnd.
x - selectedEnd.
x );
286 int yLength =
abs( unselectedEnd.
y - selectedEnd.
y );
287 int xMove = ( xLength - ( xBendCount *
grid.GetGrid().x ) )
288 *
sign( selectedEnd.
x - unselectedEnd.
x );
289 int yMove = ( yLength - ( yBendCount *
grid.GetGrid().y ) )
290 *
sign( selectedEnd.
y - unselectedEnd.
y );
310 xBendCount += yMoveBit;
311 yBendCount += xMoveBit;
316 line->MoveEnd(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
317 splitDelta.
y ? splitDelta.
y : yMove ) );
321 line->MoveStart(
VECTOR2I( splitDelta.
x ? splitDelta.
x : xMove,
322 splitDelta.
y ? splitDelta.
y : yMove ) );
343 else if( !foundAttachment )
346 line->MoveEnd( splitDelta );
348 line->MoveStart( splitDelta );
360 bool isSlice =
false;
382 if( sel && !sel->
IsNew() )
390 controls->SetAutoPan(
false );
414 bool unselect = selection.
IsHover();
417 std::vector<DANGLING_END_ITEM> internalPoints;
421 controls->ShowCursor(
true );
425 if( selection.
Empty() )
433 bool restore_state =
false;
434 bool chain_commands =
false;
440 m_cursor = controls->GetCursorPosition();
460 bool appendUndo = ( sch_item && sch_item->
IsNew() ) || isSlice;
461 bool placingNewItems = sch_item && sch_item->
IsNew();
469 internalPoints.clear();
476 if( !it->IsSelected() )
489 std::vector<SCH_ITEM*> stageTwo;
491 for(
EDA_ITEM* edaItem : selection )
494 std::vector<VECTOR2I> connections;
496 switch( item->
Type() )
502 stageTwo.emplace_back(item);
506 static_cast<SCH_LINE*
>( item )->GetSelectedPoints( connections );
512 for(
const VECTOR2I& point : connections )
520 for(
const VECTOR2I& point : item->GetConnectionPoints() )
524 for(
EDA_ITEM* item : connectedDragItems )
532 for(
EDA_ITEM* edaItem : selection )
553 static_cast<SCH_ITEM*
>( item )->GetEndPoints( internalPoints );
556 static_cast<SCH_ITEM*
>( item )->UpdateDanglingState( internalPoints );
583 else if( item->GetParent() && item->GetParent()->IsSelected() )
599 m_cursor = controls->GetCursorPosition();
603 wxASSERT_MSG(
m_anchorPos,
"Should be already set from previous cmd" );
605 else if( placingNewItems )
613 bool isPasted =
false;
619 if( item->GetParent() && item->GetParent()->IsSelected() )
625 isPasted |= ( item->GetFlags() &
IS_PASTED ) != 0;
633 selection.SetReferencePoint(
m_cursor );
650 selection.SetReferencePoint(
m_cursor );
659 controls->SetCursorPosition(
m_cursor,
false );
663 controls->SetAutoPan(
true );
670 m_cursor =
grid.BestSnapAnchor( controls->GetCursorPosition(
false ),
671 snapLayer, selection );
681 std::vector<VECTOR2I> splitMoves;
712 for(
const VECTOR2I& splitDelta : splitMoves )
715 if( splitDelta ==
VECTOR2I( 0, 0 ) )
722 if( item->GetParent() && item->GetParent()->IsSelected() )
747 if( lineEnd.second && lineEnd.first->HasFlag(
STARTPOINT ) )
748 lineEnd.first->SetStartPoint(
pin->GetPosition() );
749 else if( !lineEnd.second && lineEnd.first->HasFlag(
ENDPOINT ) )
750 lineEnd.first->SetEndPoint(
pin->GetPosition() );
786 restore_state =
true;
818 restore_state =
true;
820 chain_commands =
true;
874 }
while( ( evt =
Wait() ) );
882 selectionCopy.
Add( line );
885 selectionCopy.
Add( line );
890 controls->ForceCursorPosition(
false );
891 controls->ShowCursor(
false );
892 controls->SetAutoPan(
false );
894 if( !chain_commands )
938 item->ClearEditFlags();
942 for(
EDA_ITEM* item : selectionCopy )
943 item->ClearEditFlags();
964 std::set<SCH_ITEM*> danglers;
966 std::function<void(
SCH_ITEM* )> changeHandler =
967 [&](
SCH_ITEM* aChangedItem ) ->
void
974 if( aChangedItem->HasFlag(
IS_BROKEN) && aChangedItem->IsDangling() && !aChangedItem->IsSelected() )
976 danglers.insert( aChangedItem );
1007 for(
SCH_ITEM* item : itemsOverlapping )
1009 if( item != aOriginalItem && item->
IsConnected( aPoint ) )
1012 foundJunction = item;
1018 if( foundSymbol && foundJunction )
1020 aList.push_back( foundSymbol );
1026 aList.push_back( foundJunction );
1033 if(
test == aOriginalItem || !
test->CanConnect( aOriginalItem ) )
1036 switch(
test->Type() )
1052 if(
test->IsConnected( aPoint ) )
1053 aList.push_back(
test );
1059 aList.push_back(
test );
1072 if(
pin->IsConnected( aPoint ) )
1082 if(
test->IsConnected( aPoint ) )
1083 aList.push_back(
test );
1098 aList.push_back( label );
1110 if( line->
HitTest( aPoint, 1 ) )
1111 aList.push_back( label );
1128 std::vector<SCH_ITEM*> itemsConnectable;
1129 bool ptHasUnselectedJunction =
false;
1158 auto makeNewJunction =
1174 for(
SCH_ITEM* item : itemsOverlappingRTree )
1178 if( item == aSelectedItem || ( item->Type() !=
SCH_LINE_T && item->IsSelected() )
1184 itemsConnectable.push_back( item );
1187 for(
SCH_ITEM* item : itemsConnectable )
1189 if( item->Type() ==
SCH_JUNCTION_T && item->IsConnected( aPoint ) && !item->IsSelected() )
1191 ptHasUnselectedJunction =
true;
1208 if( ptHasUnselectedJunction )
1228 aList.push_back( line );
1242 aList.push_back( line );
1247 switch( aSelectedItem->
Type() )
1261 newWire = makeNewWire( line, aSelectedItem, aPoint, aPoint );
1264 aList.push_back( newWire );
1272 if( !line->
IsNew() )
1281 SCH_LINE* secondHalf = makeNewWire( line, line, aPoint, oldEnd );
1282 SCH_JUNCTION* junction = makeNewJunction( line, aPoint );
1320 aList.push_back( label );
1323 info.attachedLine = line;
1335 if(
pin->IsConnected( aPoint ) )
1346 newWire = makeNewWire(
pin, aSelectedItem, aPoint, aPoint );
1348 aList.push_back( newWire );
1360 if(
test->IsConnected( aPoint ) && !newWire )
1364 newWire = makeNewWire(
test, aSelectedItem, aPoint, aPoint );
1366 aList.push_back( newWire );
1378 aList.push_back(
test );
1414 aList.push_back( label );
1419 info.attachedLine = line;
1426 else if(
test->IsConnected( aPoint ) && !newWire )
1430 newWire = makeNewWire(
test, aSelectedItem, aPoint, aPoint );
1432 aList.push_back( newWire );
1461 if( line->
HitTest( point, 1 ) )
1464 aList.push_back(
test );
1467 std::vector<VECTOR2I> ends =
test->GetConnectionPoints();
1470 if( ends[0] == point )
1494 switch( aItem->
Type() )
1536 pin->SetStoredPos(
pin->GetStoredPos() + aDelta );
1537 pin->ConstrainOnEdge(
pin->GetStoredPos() );
1551 SEG currentLine(
info.attachedLine->GetStartPoint(),
info.attachedLine->GetEndPoint() );
1556 label->
Move( aDelta );
1563 static_cast<SCH_ITEM*
>( aItem )->Move( aDelta );
1575 bool appendUndo =
false;
1595 if( !it->IsSelected() )
1598 if( !selection.
IsHover() && it->IsSelected() )
1601 it->SetStoredPos( it->GetPosition() );
1606 pin->SetStoredPos(
pin->GetPosition() );
1618 for(
int ii = 0; ii < 2; ++ii )
1625 std::set<EDA_ITEM*> unique_items( drag_items.begin(), drag_items.end() );
1631 for(
EDA_ITEM* dragItem : unique_items )
1633 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1636 doMoveItem( dragItem, gridpt );
1646 doMoveItem( item, gridpt );
1653 VECTOR2I tl_gridpt =
grid.AlignGrid( topLeft ) - topLeft;
1654 VECTOR2I br_gridpt =
grid.AlignGrid( bottomRight ) - bottomRight;
1658 doMoveItem( sheet, tl_gridpt );
1679 doMoveItem(
pin, gridpt );
1681 for(
EDA_ITEM* dragItem : drag_items )
1683 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1686 doMoveItem( dragItem, gridpt );
1698 for(
const VECTOR2I& point : connections )
1701 std::map<VECTOR2I, int> shifts;
1705 for(
const VECTOR2I& conn : connections )
1711 if( shifts[gridpt] > max_count )
1713 most_common = gridpt;
1714 max_count = shifts[most_common];
1718 if( most_common !=
VECTOR2I( 0, 0 ) )
1720 for(
EDA_ITEM* dragItem : drag_items )
1722 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1725 doMoveItem( dragItem, most_common );
1749 newLine->ClearEditFlags();
1757 oldLine->ClearEditFlags();
static TOOL_ACTION duplicate
static TOOL_ACTION doDelete
static TOOL_ACTION cursorClick
static TOOL_ACTION refreshPreview
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
static TOOL_ACTION alignToGrid
static TOOL_ACTION highlightNet
static TOOL_ACTION clearSelection
Clears the current selection.
static TOOL_ACTION moveActivate
static TOOL_ACTION rotateCCW
static TOOL_ACTION restartMove
static TOOL_ACTION rotateCW
static TOOL_ACTION selectOnPCB
static const std::vector< KICAD_T > MovableItems
Implements an R-tree for fast spatial and type indexing of schematic items.
EE_TYPE Overlapping(const BOX2I &aRect) const
static const TOOL_EVENT SelectedItemsModified
Selected items were moved, this can be very high frequency on the canvas, use with care.
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...
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,...
void AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen)
Add an item to the screen (and view) aScreen is the screen the item is located on,...
Schematic editor (Eeschema) main window.
void RollbackSchematicFromUndo()
Perform an undo of the last edit WITHOUT logging a corresponding redo.
bool SchematicCleanUp(SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag and update other data struc...
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
void SelectUnit(SCH_SYMBOL *aSymbol, int aUnit)
SCH_JUNCTION * AddJunction(SCH_SCREEN *aScreen, const VECTOR2I &aPos, bool aAppendToUndo, bool aFinal=true)
void TestDanglingEnds()
Test all of the connectable objects in the schematic for unused connection points.
void AutoRotateItem(SCH_SCREEN *aScreen, SCH_ITEM *aItem)
Automatically set the rotation of an item (if the item supports it)
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 bool IsConnectable() const
void ClearFieldsAutoplaced()
void SetLayer(SCH_LAYER_ID aLayer)
Set the layer this item is on.
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
void SetConnectivityDirty(bool aDirty=true)
bool IsConnected(const VECTOR2I &aPoint) const
Test the item to see if it is connected to aPoint.
virtual bool IsMovableFromAnchorPoint() 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.
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()
Saves 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
Gets the angle between the start and end lines.
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
bool IsBus() const
Return true if the line is a bus.
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()
Gets the full RTree, usually for iterating.
bool IsExplicitJunctionNeeded(const VECTOR2I &aPosition) const
Indicates 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()
TRANSFORM & GetTransform()
VECTOR2I GetPosition() const override
void SetPosition(const VECTOR2I &aPosition) 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)
const 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.
VECTOR2I GetReferencePoint() const
void SetReferencePoint(const VECTOR2I &aP)
bool Empty() const
Checks if there is anything selected.
bool HasReferencePoint() 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_CMP
@ ID_POPUP_SCH_SELECT_UNIT_SYM_MAX
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
@ REPAINT
Item needs to be redrawn.
bool signbit(T v)
Integral version of std::signbit that works all compilers.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
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.