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;
411 bool isLineModeConstrained =
false;
414 isLineModeConstrained = cfg->m_Drawing.line_mode != LINE_MODE::LINE_MODE_FREE;
424 if( sel && !sel->
IsNew() )
457 if( userSelection.
GetSize() == 1 )
477 bool unselect = selection.
IsHover();
480 std::vector<DANGLING_END_ITEM> internalPoints;
489 if( selection.
Empty() )
497 bool restore_state =
false;
522 bool placingNewItems = sch_item && sch_item->
IsNew();
530 internalPoints.clear();
537 if( !it->IsSelected() )
550 std::vector<SCH_ITEM*> stageTwo;
552 for(
EDA_ITEM* edaItem : selection )
555 std::vector<VECTOR2I> connections;
557 switch( item->
Type() )
563 stageTwo.emplace_back(item);
567 static_cast<SCH_LINE*
>( item )->GetSelectedPoints( connections );
573 for(
const VECTOR2I& point : connections )
581 for(
const VECTOR2I& point : item->GetConnectionPoints() )
585 for(
EDA_ITEM* item : connectedDragItems )
593 for(
EDA_ITEM* edaItem : selection )
614 static_cast<SCH_ITEM*
>( item )->GetEndPoints( internalPoints );
616 std::vector<DANGLING_END_ITEM> endPointsByType = internalPoints;
617 std::vector<DANGLING_END_ITEM> endPointsByPos = endPointsByType;
621 static_cast<SCH_ITEM*
>( item )->UpdateDanglingState( endPointsByType, endPointsByPos );
626 snapLayer =
grid.GetSelectionGrid( selection );
632 if( schItem->
IsNew() )
643 enteredGroup->AddItem( schItem );
660 shape->SetHatchingDirty();
661 shape->UpdateHatching();
669 RECURSE_MODE::RECURSE );
680 wxASSERT_MSG(
m_anchorPos,
"Should be already set from previous cmd" );
682 else if( placingNewItems )
690 bool isPasted =
false;
696 if( item->GetParent() && item->GetParent()->IsSelected() )
702 isPasted |= ( item->GetFlags() &
IS_PASTED ) != 0;
710 selection.SetReferencePoint(
m_cursor );
727 selection.SetReferencePoint(
m_cursor );
747 snapLayer, selection );
757 std::vector<VECTOR2I> splitMoves;
788 for(
const VECTOR2I& splitDelta : splitMoves )
791 if( splitDelta ==
VECTOR2I( 0, 0 ) )
798 if( item->GetParent() && item->GetParent()->IsSelected() )
805 if(
m_isDrag && isLineModeConstrained
821 if( lineEnd.second && lineEnd.first->HasFlag(
STARTPOINT ) )
822 lineEnd.first->SetStartPoint(
pin->GetPosition() );
823 else if( !lineEnd.second && lineEnd.first->HasFlag(
ENDPOINT ) )
824 lineEnd.first->SetEndPoint(
pin->GetPosition() );
862 restore_state =
true;
975 }
while( ( evt =
Wait() ) );
983 selectionCopy.
Add( line );
986 selectionCopy.
Add( line );
991 newLine->ClearEditFlags();
998 oldLine->ClearEditFlags();
1022 sch_item->SetConnectivityDirty(
true );
1025 if( selection.GetSize() == 1 && selection.Front()->IsNew() )
1055 item->ClearEditFlags();
1059 for(
EDA_ITEM* item : selectionCopy )
1060 item->ClearEditFlags();
1072 return !restore_state;
1081 std::set<SCH_ITEM*> danglers;
1083 std::function<void(
SCH_ITEM* )> changeHandler =
1084 [&](
SCH_ITEM* aChangedItem ) ->
void
1091 if( aChangedItem->HasFlag(
IS_BROKEN) && aChangedItem->IsDangling()
1092 && !aChangedItem->IsSelected() )
1094 danglers.insert( aChangedItem );
1124 for(
SCH_ITEM* item : itemsOverlapping )
1126 if( item != aOriginalItem && item->
IsConnected( aPoint ) )
1129 foundJunction = item;
1135 if( foundSymbol && foundJunction )
1137 aList.push_back( foundSymbol );
1143 aList.push_back( foundJunction );
1150 if(
test == aOriginalItem || !
test->CanConnect( aOriginalItem ) )
1153 switch(
test->Type() )
1169 if(
test->IsConnected( aPoint ) )
1170 aList.push_back(
test );
1176 aList.push_back(
test );
1189 if(
pin->IsConnected( aPoint ) )
1191 if(
pin->IsSelected() )
1194 aList.push_back(
pin );
1204 if(
test->IsConnected( aPoint ) )
1205 aList.push_back(
test );
1220 aList.push_back( label );
1232 if( line->
HitTest( aPoint, 1 ) )
1233 aList.push_back( label );
1250 std::vector<SCH_ITEM*> itemsConnectable;
1251 bool ptHasUnselectedJunction =
false;
1274 if(
dynamic_cast<const SCH_LINE*
>( selected ) )
1276 else if(
dynamic_cast<const SCH_LINE*
>( fixed ) )
1286 auto makeNewJunction =
1303 for(
SCH_ITEM* item : itemsOverlappingRTree )
1311 if( !
pin->IsSelected()
1313 &&
pin->CanConnect( aSelectedItem ) )
1315 itemsConnectable.push_back(
pin );
1324 if( item == aSelectedItem
1325 || ( item->Type() !=
SCH_LINE_T && item->IsSelected() )
1331 itemsConnectable.push_back( item );
1334 for(
SCH_ITEM* item : itemsConnectable )
1336 if( item->Type() ==
SCH_JUNCTION_T && item->IsConnected( aPoint ) && !item->IsSelected() )
1338 ptHasUnselectedJunction =
true;
1355 if( ptHasUnselectedJunction )
1375 aList.push_back( line );
1389 aList.push_back( line );
1394 switch( aSelectedItem->
Type() )
1408 newWire = makeNewWire( aCommit, line, aSelectedItem, aPoint, aPoint );
1411 aList.push_back( newWire );
1416 if( !line->
IsNew() )
1422 makeNewWire( aCommit, line, line, aPoint, oldEnd );
1423 makeNewJunction( aCommit, line, aPoint );
1455 aList.push_back( label );
1458 info.attachedLine = line;
1470 if(
pin->IsConnected( aPoint ) )
1481 newWire = makeNewWire( aCommit,
pin, aSelectedItem, aPoint, aPoint );
1483 aList.push_back( newWire );
1492 if(
test->IsConnected( aPoint ) && !newWire )
1496 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1498 aList.push_back( newWire );
1507 aList.push_back(
test );
1542 aList.push_back( label );
1547 info.attachedLine = line;
1554 else if(
test->IsConnected( aPoint ) && !newWire )
1558 newWire = makeNewWire( aCommit,
test, aSelectedItem, aPoint, aPoint );
1560 aList.push_back( newWire );
1586 if( line->
HitTest( point, 1 ) )
1589 aList.push_back(
test );
1592 std::vector<VECTOR2I> ends =
test->GetConnectionPoints();
1595 if( ends[0] == point )
1619 switch( aItem->
Type() )
1661 pin->SetStoredPos(
pin->GetStoredPos() + aDelta );
1662 pin->ConstrainOnEdge(
pin->GetStoredPos(), true );
1676 SEG currentLine(
info.attachedLine->GetStartPoint(),
info.attachedLine->GetEndPoint() );
1681 label->
Move( aDelta );
1688 static_cast<SCH_ITEM*
>( aItem )->Move( aDelta );
1721 if( !it->IsSelected() )
1724 if( !selection.
IsHover() && it->IsSelected() )
1727 it->SetStoredPos( it->GetPosition() );
1732 pin->SetStoredPos(
pin->GetPosition() );
1744 for(
int ii = 0; ii < 2; ++ii )
1751 std::set<EDA_ITEM*> unique_items( drag_items.begin(), drag_items.end() );
1757 for(
EDA_ITEM* dragItem : unique_items )
1759 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1762 doMoveItem( dragItem,
delta );
1772 doMoveItem( item,
delta );
1779 VECTOR2I tl_delta =
grid.AlignGrid( topLeft, selectionGrid ) - topLeft;
1780 VECTOR2I br_delta =
grid.AlignGrid( bottomRight, selectionGrid ) - bottomRight;
1784 doMoveItem( sheet, tl_delta );
1795 if(
pin->GetSide() == SHEET_SIDE::TOP ||
pin->GetSide() == SHEET_SIDE::LEFT )
1796 newPos =
pin->GetPosition() + tl_delta;
1798 newPos =
pin->GetPosition() + br_delta;
1810 for(
EDA_ITEM* dragItem : drag_items )
1812 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1815 doMoveItem( dragItem,
delta );
1826 for(
const VECTOR2I& point : connections )
1829 std::map<VECTOR2I, int> shifts;
1833 for(
const VECTOR2I& conn : connections )
1835 VECTOR2I gridpt =
grid.AlignGrid( conn, selectionGrid ) - conn;
1839 if( shifts[gridpt] > max_count )
1841 most_common = gridpt;
1842 max_count = shifts[most_common];
1846 if( most_common !=
VECTOR2I( 0, 0 ) )
1848 doMoveItem( item, most_common );
1850 for(
EDA_ITEM* dragItem : drag_items )
1852 if( dragItem->GetParent() && dragItem->GetParent()->IsSelected() )
1855 doMoveItem( dragItem, most_common );
1868 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 & 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...
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)
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.
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...
void CleanUp(SCH_COMMIT *aCommit, SCH_SCREEN *aScreen=nullptr)
Perform routine schematic cleaning including breaking wire and buses and deleting identical objects s...
static TOOL_ACTION rotateCCW
static TOOL_ACTION toCLabel
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 toTextBox
static TOOL_ACTION highlightNet
static TOOL_ACTION repeatDrawItem
static TOOL_ACTION toGLabel
static TOOL_ACTION selectOnPCB
void RemoveFromScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen) override
Remove an item from 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 AddToScreen(EDA_ITEM *aItem, SCH_SCREEN *aScreen=nullptr) override
Add an item to 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.
SCHEMATIC & Schematic() const
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.
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)
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 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
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.
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