30#include <wx/translation.h>
116 if( !connection || !connection->
IsBus() || connection->
Members().empty() )
131 for(
const std::shared_ptr<SCH_CONNECTION>& member : connection->
Members() )
134 wxString
name = member->FullLocalName();
141 for(
const std::shared_ptr<SCH_CONNECTION>& sub_member : member->Members() )
144 name = sub_member->FullLocalName();
150 Append(
id,
name, wxEmptyString );
192 const auto busGetter =
198 std::shared_ptr<BUS_UNFOLD_MENU>
199 busUnfoldMenu = std::make_shared<BUS_UNFOLD_MENU>( busGetter );
200 busUnfoldMenu->SetTool(
this );
201 m_menu->RegisterSubMenu( busUnfoldMenu );
203 std::shared_ptr<BUS_UNFOLD_MENU> selBusUnfoldMenu = std::make_shared<BUS_UNFOLD_MENU>( busGetter );
220 auto belowRootSheetCondition =
223 return m_frame->GetCurrentSheet().Last() != &
m_frame->Schematic().Root();
237 auto& ctxMenu =
m_menu->GetMenu();
244 ctxMenu.AddSeparator( 10 );
255 ctxMenu.AddSeparator( 100 );
266 ctxMenu.AddSeparator( 200 );
326 wxString* netPtr = aEvent.
Parameter<wxString*>();
340 const auto busGetter = [
this]()
354 std::optional<int>
id = evt->GetCommandId();
356 if(
id && ( *
id > 0 ) )
357 net = *evt->Parameter<wxString*>();
397 const std::optional<VECTOR2I>& aPos )
404 if ( bus ==
nullptr )
406 wxASSERT_MSG(
false, wxString::Format(
"Couldn't find the originating bus line (but had a net: %s )",
437 std::vector<DANGLING_END_ITEM> endPointsByType;
440 item->GetEndPoints( endPointsByType );
442 std::vector<DANGLING_END_ITEM> endPointsByPos = endPointsByType;
444 m_busUnfold.entry->UpdateDanglingState( endPointsByType, endPointsByPos );
462 if(
pin->GetPosition() == aPosition )
476 wxCHECK_RET( aSegments.first && aSegments.second,
477 wxT(
"Cannot compute break point of NULL line segment." ) );
480 SCH_LINE* segment = aSegments.first;
481 SCH_LINE* nextSegment = aSegments.second;
484 int xDir =
delta.x > 0 ? 1 : -1;
485 int yDir =
delta.y > 0 ? 1 : -1;
488 bool preferHorizontal;
511 aPosition.
x +=
KiROUND(
getView()->GetGAL()->GetGridSize().x * direction );
514 preferHorizontal =
true;
515 preferVertical =
false;
519 auto breakVertical = [&]()
mutable
527 midPoint.
y = aPosition.
y - yDir * abs(
delta.x );
531 midPoint.
x = aPosition.
x;
537 midPoint.
y = aPosition.
y;
542 auto breakHorizontal = [&]()
mutable
549 midPoint.
x = aPosition.
x - xDir * abs(
delta.y );
555 midPoint.
y = aPosition.
y;
559 midPoint.
x = aPosition.
x;
569 else if( preferHorizontal )
583 preferVertical =
false;
584 preferHorizontal =
false;
587 && ( ( abs( deltaMidpoint.
x ) > abs(
delta.x ) )
588 || ( abs( deltaMidpoint.
y ) > abs(
delta.y ) ) ) )
590 preferVertical =
false;
591 preferHorizontal =
false;
594 if( !preferHorizontal && !preferVertical )
609 int aType,
bool aQuitOnDraw )
616 int lastMode =
m_frame->eeconfig()->m_Drawing.line_mode;
617 static bool posture =
false;
657 m_view->ShowPreview(
false );
683 bool isSyntheticClick = ( segment ||
m_busUnfold.in_progress ) && evt->IsActivate()
684 && evt->HasPosition() && evt->Matches( aTool );
689 grid.SetUseGrid(
getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
700 VECTOR2D eventPosition = evt->HasPosition() ? evt->Position()
703 VECTOR2I cursorPos =
grid.BestSnapAnchor( eventPosition, gridType, segment );
707 if( currentMode != lastMode )
733 lastMode = currentMode;
739 if( evt->IsCancelInteractive() )
741 m_frame->GetInfoBar()->Dismiss();
759 else if( evt->IsActivate() && !isSyntheticClick )
763 m_frame->ShowInfoBarMsg(
_(
"Press <ESC> to cancel drawing." ) );
764 evt->SetPassEvent(
false );
768 if( evt->IsMoveTool() )
789 aCommit.
Push(
_(
"Draw Wires" ) );
802 || ( segment && evt->IsDblClick(
BUT_LEFT ) )
803 || isSyntheticClick )
820 else if( !segment->
IsNull()
830 aCommit.
Push(
_(
"Draw Wires" ) );
840 int placedSegments = 1;
850 for(
int i = 0; i < placedSegments; i++ )
863 if( evt->IsDblClick(
BUT_LEFT ) && segment )
865 if( twoSegments &&
m_wires.size() >= 2 )
868 currentMode, posture );
874 aCommit.
Push(
_(
"Draw Wires" ) );
896 bool flipX = ( cursor_delta.
x < 0 );
897 bool flipY = ( cursor_delta.
y < 0 );
903 int ySign = flipY ? -1 : 1;
904 int xSign = flipX ? -1 : 1;
913 m_frame->UpdateItem( entry,
false,
true );
929 if( twoSegments &&
m_wires.size() >= 2 )
932 currentMode, posture );
942 if( !wire->IsNull() )
943 m_view->AddToPreview( wire->Clone() );
946 std::vector<SCH_ITEM*> previewItems;
950 if( !wire->IsNull() )
951 previewItems.push_back( wire );
960 m_view->AddToPreview( jct,
true );
981 if( twoSegments &&
m_wires.size() >= 2 )
984 currentMode, posture );
993 if( !wire->IsNull() )
994 m_view->AddToPreview( wire->Clone() );
1000 evt->SetPassEvent();
1029 if( !wire->IsNull() )
1030 m_view->AddToPreview( wire->Clone() );
1050 contextMenuPos = cursorPos;
1058 wxASSERT_MSG( !segment,
"Bus unfold event received when already drawing!" );
1061 wxString net = *evt->Parameter<wxString*>();
1062 segment =
doUnfoldBus( aCommit, net, contextMenuPos );
1088 evt->SetPassEvent();
1108 aSegment =
m_frame->GetScreen()->GetLine( aPos, 0, aType );
1130 m_wires.push_back( aSegment );
1136 if(
m_frame->eeconfig()->m_Drawing.line_mode )
1140 m_wires.push_back( aSegment );
1178 if( next_it ==
m_wires.end() )
1210 std::vector<VECTOR2I> new_ends;
1218 std::vector<VECTOR2I> tmpends = wire->GetConnectionPoints();
1220 new_ends.insert( new_ends.end(), tmpends.begin(), tmpends.end() );
1222 for(
const VECTOR2I& pt : connections )
1225 new_ends.push_back( pt );
1228 aCommit.
Added( wire, screen );
1250 for(
size_t ii = 1; ii <
m_wires.size(); ++ii )
1257 m_frame->AddToScreen( wire, screen );
1262 m_view->ShowPreview(
false );
1268 m_frame->Schematic().CleanUp( &aCommit );
1270 std::vector<SCH_ITEM*> symbols;
1273 symbols.push_back( symbol );
1277 std::vector<VECTOR2I> pts = symbol->GetConnectionPoints();
1279 if( pts.size() > 2 )
1282 for(
auto pt = pts.begin(); pt != pts.end(); pt++ )
1284 for(
auto secondPt = pt + 1; secondPt != pts.end(); secondPt++ )
1285 m_frame->TrimWire( &aCommit, *pt, *secondPt );
1289 for(
const VECTOR2I& pt : new_ends )
1291 if(
m_frame->GetScreen()->IsExplicitJunctionNeeded( pt ) )
1299 item->ClearEditFlags();
1308 std::set<SCH_LINE*> lines;
1312 lines.insert(
static_cast<SCH_LINE*
>( item ) );
1314 for(
unsigned ii = 0; ii < aSelection->
GetSize(); ii++ )
1327 std::vector<VECTOR2I> conn_pts;
1332 conn_pts.push_back( pt );
1334 if( conn_pts.size() > 2 )
1338 if( conn_pts.size() == 2 )
1339 m_frame->TrimWire( aCommit, conn_pts[0], conn_pts[1] );
1350 std::deque<EDA_ITEM*> allItems;
1354 allItems.push_back( item );
1358 static_cast<SCH_GROUP*
>( item )->RunOnChildren(
1361 allItems.push_back( child );
1377 aCommit->
Modify( aSegment, aScreen );
1383 m_frame->AddToScreen( newSegment, aScreen );
1385 aCommit->
Added( newSegment, aScreen );
1387 *aNewSegment = newSegment;
1393 bool brokenSegments =
false;
1398 BreakSegment( aCommit, wire, aPos, &new_line, aScreen );
1399 brokenSegments =
true;
1402 return brokenSegments;
1408 bool brokenSegments =
false;
1410 std::set<VECTOR2I> point_set;
1413 point_set.insert( item->GetPosition() );
1419 point_set.insert( entry->
GetEnd() );
1422 for(
const VECTOR2I& pt : point_set )
1425 brokenSegments =
true;
1428 return brokenSegments;
1437 m_frame->AddToScreen( junction, aScreen );
1438 aCommit->
Added( junction, aScreen );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static TOOL_ACTION doDelete
static TOOL_ACTION selectionClear
Clear the current selection.
static TOOL_ACTION refreshPreview
static TOOL_ACTION finishInteractive
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.
static void sort_dangling_end_items(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos)
Both contain the same information.
A base class for most all the KiCad significant classes used in schematics and boards.
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
virtual void SetParent(EDA_ITEM *aParent)
EE_TYPE Overlapping(const BOX2I &aRect) const
EE_TYPE OfType(KICAD_T aType) const
An interface for classes handling user events controlling the view behavior such as zooming,...
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 WarpMouseCursor(const VECTOR2D &aPosition, bool aWorldCoordinates=false, bool aWarpView=false)=0
If enabled (.
virtual void SetCrossHairCursorPosition(const VECTOR2D &aPosition, bool aWarpView=true)=0
Move the graphic crosshair cursor to the requested position expressed in world coordinates.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
SCH_SHEET_PATH & CurrentSheet() const
static TOOL_ACTION rotateCCW
static TOOL_ACTION placeClassLabel
static TOOL_ACTION clearHighlight
static TOOL_ACTION placeGlobalLabel
static TOOL_ACTION leaveSheet
static TOOL_ACTION breakWire
static TOOL_ACTION drawLines
static TOOL_ACTION placeHierLabel
static TOOL_ACTION selectConnection
If current selection is a wire or bus, expand to entire connection.
static TOOL_ACTION placeLabel
static TOOL_ACTION drawWire
static TOOL_ACTION rotateCW
static TOOL_ACTION placeJunction
static TOOL_ACTION selectNode
Select the junction, wire or bus segment under the cursor.
static TOOL_ACTION unfoldBus
static TOOL_ACTION drawBus
static TOOL_ACTION undoLastSegment
static TOOL_ACTION switchSegmentPosture
void SetSize(const VECTOR2I &aSize)
VECTOR2I GetPosition() const override
Class for a wire to bus entry.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
const std::vector< std::shared_ptr< SCH_CONNECTION > > & Members() const
static wxString PrintBusForUI(const wxString &aString)
Schematic editor (Eeschema) main window.
const wxString & GetHighlightedConnection() const
A set of SCH_ITEMs (i.e., without duplicates).
Base class for any item which can be embedded within the SCHEMATIC container class,...
SCH_ITEM * Duplicate(bool addToParentGroup, SCH_COMMIT *aCommit=nullptr, bool doClone=false) const
Routine to create a new copy of given item.
virtual bool IsConnectable() const
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Segment description base class to describe items which have 2 end points (track, wire,...
void SetStartPoint(const VECTOR2I &aPosition)
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
SEG GetSeg() const
Get the geometric aspect of the wire as a SEG.
SCH_LINE * MergeOverlap(SCH_SCREEN *aScreen, SCH_LINE *aLine, bool aCheckJunctions)
Check line against aLine to see if it overlaps and merge if it does.
SCH_LINE * BreakAt(SCH_COMMIT *aCommit, const VECTOR2I &aPoint)
Break this segment into two at the specified point.
void SetEndPoint(const VECTOR2I &aPosition)
std::vector< SCH_LINE * > GetBusesAndWires(const VECTOR2I &aPosition, bool aIgnoreEndpoints=false) const
Return buses and wires passing through aPosition.
EE_RTREE & Items()
Get the full RTree, usually for iterating.
bool IsTerminalPoint(const VECTOR2I &aPosition, int aLayer) const
Test if aPosition is a connection point on aLayer.
std::vector< VECTOR2I > GetNeededJunctions(const std::deque< EDA_ITEM * > &aItems) const
Return the unique set of points belonging to aItems where a junction is needed.
std::vector< VECTOR2I > GetConnections() const
Collect a unique list of all possible connection points in the schematic.
BOX2I GetBoundingBox() const override
SCH_SCREEN * LastScreen()
Define a sheet pin (label) used in sheets to create hierarchical schematics.
SHEET_SIDE GetSide() const
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
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 MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static bool Idle(const SELECTION &aSelection)
Test if there no items selected or being edited.
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
virtual KIGFX::VIEW_ITEM * GetItem(unsigned int aIdx) const override
virtual unsigned int GetSize() const override
Return the number of stored items.
std::deque< EDA_ITEM * > & Items()
#define IS_CHANGED
Item was edited, and modified.
#define IS_NEW
New item, just created.
#define IS_BROKEN
Is a segment just broken by BreakSegment.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define IS_MOVING
Item being moved.
@ ID_POPUP_SCH_UNFOLD_BUS_END
@ ID_POPUP_SCH_UNFOLD_BUS
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...
bool signbit(T v)
Integral version of std::signbit that works all compilers.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ BUS
This item represents a bus vector.
Class to handle a set of SCH_ITEMs.
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
Settings for bus unfolding that are persistent across invocations of the tool.
SPIN_STYLE label_spin_style
bool IsPointOnSegment(const VECTOR2I &aSegStart, const VECTOR2I &aSegEnd, const VECTOR2I &aTestPoint)
Test if aTestPoint is on line defined by aSegStart and aSegEnd.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D