Eeschema: Allow auto-wiring / drawing from unconnected bus and graphic line endpoints

Fixes https://gitlab.com/kicad/code/kicad/issues/7537
This commit is contained in:
James Jackson 2021-02-17 19:43:07 +00:00 committed by Seth Hillbrand
parent d0b91b1106
commit 48853d0c88
6 changed files with 87 additions and 41 deletions

View File

@ -127,6 +127,8 @@ public:
return ( m_type == CONNECTION_TYPE::NET );
}
bool IsUnconnected() const { return ( m_type == CONNECTION_TYPE::NONE ); }
bool IsDirty() const { return m_dirty; }
void SetDirty() { m_dirty = true; }
void ClearDirty() { m_dirty = false; }

View File

@ -64,6 +64,8 @@ enum FIELDS_AUTOPLACED
enum DANGLING_END_T
{
UNKNOWN = 0,
GRAPHIC_START_END,
GRAPHIC_END_END,
WIRE_START_END,
WIRE_END_END,
BUS_START_END,

View File

@ -566,19 +566,29 @@ SCH_LINE* SCH_LINE::MergeOverlap( SCH_SCREEN* aScreen, SCH_LINE* aLine, bool aCh
void SCH_LINE::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{
if( IsGraphicLine() )
return;
DANGLING_END_T startType, endType;
if( ( GetLayer() == LAYER_BUS ) || ( GetLayer() == LAYER_WIRE ) )
switch( GetLayer() )
{
DANGLING_END_ITEM item( (GetLayer() == LAYER_BUS) ? BUS_START_END : WIRE_START_END, this,
m_start );
aItemList.push_back( item );
DANGLING_END_ITEM item1( (GetLayer() == LAYER_BUS) ? BUS_END_END : WIRE_END_END, this,
m_end );
aItemList.push_back( item1 );
case LAYER_WIRE:
startType = WIRE_START_END;
endType = WIRE_END_END;
break;
case LAYER_BUS:
startType = BUS_START_END;
endType = BUS_END_END;
break;
default:
startType = GRAPHIC_START_END;
endType = GRAPHIC_END_END;
break;
}
DANGLING_END_ITEM item( startType, this, m_start );
aItemList.push_back( item );
DANGLING_END_ITEM item1( endType, this, m_end );
aItemList.push_back( item1 );
}
@ -590,32 +600,36 @@ bool SCH_LINE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
m_startIsDangling = m_endIsDangling = true;
if( GetLayer() == LAYER_WIRE )
for( DANGLING_END_ITEM item : aItemList )
{
for( DANGLING_END_ITEM item : aItemList )
{
if( item.GetItem() == this )
continue;
if( item.GetItem() == this )
continue;
if( item.GetType() == BUS_START_END ||
item.GetType() == BUS_END_END ||
item.GetType() == BUS_ENTRY_END )
continue;
if( ( IsWire()
&& ( item.GetType() == BUS_START_END || item.GetType() == BUS_END_END
|| item.GetType() == BUS_ENTRY_END ) )
|| ( IsBus()
&& ( item.GetType() == WIRE_START_END || item.GetType() == WIRE_END_END
|| item.GetType() == PIN_END ) )
|| ( IsGraphicLine()
&& ( item.GetType() != GRAPHIC_START_END && item.GetType() != GRAPHIC_END_END ) ) )
continue;
if( m_start == item.GetPosition() )
m_startIsDangling = false;
if( m_start == item.GetPosition() )
m_startIsDangling = false;
if( m_end == item.GetPosition() )
m_endIsDangling = false;
if( m_end == item.GetPosition() )
m_endIsDangling = false;
if( !m_startIsDangling && !m_endIsDangling )
break;
}
if( !m_startIsDangling && !m_endIsDangling )
break;
}
else if( GetLayer() == LAYER_BUS || IsGraphicLine() )
if( IsBus() || IsGraphicLine() )
{
// Lines on the notes layer and the bus layer cannot be tested for dangling ends.
previousStartState = previousEndState = m_startIsDangling = m_endIsDangling = false;
// Force unchanged return state for graphic lines and busses
previousStartState = m_startIsDangling;
previousEndState = m_endIsDangling;
}
return ( previousStartState != m_startIsDangling ) || ( previousEndState != m_endIsDangling );
@ -903,6 +917,11 @@ bool SCH_LINE::IsWire() const
return ( GetLayer() == LAYER_WIRE );
}
bool SCH_LINE::IsBus() const
{
return ( GetLayer() == LAYER_BUS );
}
bool SCH_LINE::UsesDefaultStroke() const
{

View File

@ -266,6 +266,13 @@ public:
*/
bool IsWire() const;
/**
* Returns true if the line is a bus.
*
* @return true if this line is on the bus layer.
*/
bool IsBus() const;
private:
bool doIsConnected( const wxPoint& aPosition ) const override;
};

View File

@ -1272,13 +1272,13 @@ void SCH_PAINTER::draw( const SCH_LINE *aLine, int aLayer )
}
}
if( aLine->IsStartDangling() )
if( aLine->IsStartDangling() && aLine->IsWire() )
{
drawDanglingSymbol( aLine->GetStartPoint(), getLineWidth( aLine, drawingShadows ),
drawingShadows );
}
if( aLine->IsEndDangling() )
if( aLine->IsEndDangling() && aLine->IsWire() )
{
drawDanglingSymbol( aLine->GetEndPoint(), getLineWidth( aLine, drawingShadows ),
drawingShadows );

View File

@ -329,6 +329,7 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
bool displayWireCursor = false;
bool displayBusCursor = false;
bool displayLineCursor = false;
KIID rolloverItem = lastRolloverItem;
m_additive = m_subtractive = m_exclusive_or = false;
@ -374,15 +375,21 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
OPT_TOOL_EVENT newEvt;
SCH_CONNECTION* connection = collector[0]->Connection();
if( connection && connection->IsBus() )
{
newEvt = EE_ACTIONS::drawBus.MakeEvent();
}
else
if( ( connection && ( connection->IsNet() || connection->IsUnconnected() ) )
|| collector[0]->Type() == SCH_COMPONENT_T )
{
newEvt = EE_ACTIONS::drawWire.MakeEvent();
}
else if( connection && connection->IsBus() )
{
newEvt = EE_ACTIONS::drawBus.MakeEvent();
}
else if( collector[0]->Type() == SCH_LINE_T
&& static_cast<SCH_LINE*>( collector[0] )->IsGraphicLine() )
{
newEvt = EE_ACTIONS::drawLines.MakeEvent();
}
auto* params = newEvt->Parameter<DRAW_SEGMENT_EVENT_PARAMS*>();
auto* newParams = new DRAW_SEGMENT_EVENT_PARAMS();
@ -390,7 +397,6 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
newParams->quitOnDraw = true;
newEvt->SetParameter( newParams );
getViewControls()->ForceCursorPosition( true, snappedCursorPos );
newEvt->SetMousePosition( snappedCursorPos );
newEvt->SetHasPosition( true );
@ -586,13 +592,19 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
SCH_CONNECTION* connection = collector[0]->Connection();
if( connection && connection->IsBus() )
if( ( connection && ( connection->IsNet() || connection->IsUnconnected() ) )
|| collector[0]->Type() == SCH_COMPONENT_T )
{
displayWireCursor = true;
}
else if( connection && connection->IsBus() )
{
displayBusCursor = true;
}
else
else if( collector[0]->Type() == SCH_LINE_T
&& static_cast<SCH_LINE*>( collector[0] )->IsGraphicLine() )
{
displayWireCursor = true;
displayLineCursor = true;
}
getViewControls()->ForceCursorPosition( true, snappedCursorPos );
@ -654,6 +666,10 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
m_nonModifiedCursor = KICURSOR::LINE_BUS;
}
else if( displayLineCursor )
{
m_nonModifiedCursor = KICURSOR::LINE_GRAPHIC;
}
else if( rolloverItem != niluuid )
{
m_nonModifiedCursor = KICURSOR::HAND;