Draw dangling symbols on a separate layer.

This allows us to draw them in front of wires, pins, and most
importantly, junction dots.

Fixes https://gitlab.com/kicad/code/kicad/issues/9667
This commit is contained in:
Jeff Young 2021-12-06 18:50:00 +00:00
parent 04b0435c45
commit 2e342ed8c9
11 changed files with 122 additions and 55 deletions

View File

@ -47,6 +47,12 @@
#include <wx/msgdlg.h>
std::set<int> g_excludedLayers =
{
LAYER_DANGLING
};
PANEL_EESCHEMA_COLOR_SETTINGS::PANEL_EESCHEMA_COLOR_SETTINGS( SCH_BASE_FRAME* aFrame,
wxWindow* aParent ) :
PANEL_COLOR_SETTINGS( aParent ),
@ -78,7 +84,12 @@ PANEL_EESCHEMA_COLOR_SETTINGS::PANEL_EESCHEMA_COLOR_SETTINGS( SCH_BASE_FRAME* aF
m_currentSettings = new COLOR_SETTINGS( *current );
for( int id = SCH_LAYER_ID_START; id < SCH_LAYER_ID_END; id++ )
{
if( g_excludedLayers.count( id ) )
continue;
m_validLayers.push_back( id );
}
m_backgroundLayer = LAYER_SCHEMATIC_BACKGROUND;
@ -167,7 +178,7 @@ bool PANEL_EESCHEMA_COLOR_SETTINGS::validateSave( bool aQuiet )
bool PANEL_EESCHEMA_COLOR_SETTINGS::saveCurrentTheme( bool aValidate)
{
for( auto layer : m_validLayers )
for( int layer : m_validLayers )
{
COLOR4D color = m_currentSettings->GetColor( layer );

View File

@ -151,9 +151,10 @@ void SCH_BUS_ENTRY_BASE::SwapData( SCH_ITEM* aItem )
void SCH_BUS_ENTRY_BASE::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 2;
aLayers[0] = Type() == SCH_BUS_BUS_ENTRY_T ? LAYER_BUS : LAYER_WIRE;
aLayers[1] = LAYER_SELECTION_SHADOWS;
aCount = 3;
aLayers[0] = LAYER_DANGLING;
aLayers[1] = Type() == SCH_BUS_BUS_ENTRY_T ? LAYER_BUS : LAYER_WIRE;
aLayers[2] = LAYER_SELECTION_SHADOWS;
}

View File

@ -180,9 +180,10 @@ void SCH_LINE::Show( int nestLevel, std::ostream& os ) const
void SCH_LINE::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 2;
aLayers[0] = m_layer;
aLayers[1] = LAYER_SELECTION_SHADOWS;
aCount = 3;
aLayers[0] = LAYER_DANGLING;
aLayers[1] = m_layer;
aLayers[2] = LAYER_SELECTION_SHADOWS;
}

View File

@ -737,8 +737,13 @@ int SCH_PAINTER::externalPinDecoSize( const LIB_PIN &aPin )
// Draw the target (an open circle) for a pin which has no connection or is being moved.
void SCH_PAINTER::drawPinDanglingSymbol( const VECTOR2I& aPos, bool aDrawingShadows )
void SCH_PAINTER::drawPinDanglingSymbol( const VECTOR2I& aPos, const COLOR4D& aColor,
bool aDrawingShadows )
{
// Dangling symbols must be drawn in a slightly different colour so they can be seen when
// they overlap with a junction dot.
m_gal->SetStrokeColor( aColor.Brightened( 0.3 ) );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( aDrawingShadows ? getShadowWidth()
@ -770,13 +775,21 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
}
else
{
if( dangling && aPin->IsPowerConnection() )
drawPinDanglingSymbol( pos, drawingShadows );
if( aLayer == LAYER_DANGLING && dangling && aPin->IsPowerConnection() )
drawPinDanglingSymbol( pos, color, drawingShadows );
return;
}
}
if( aLayer == LAYER_DANGLING )
{
if( dangling )
drawPinDanglingSymbol( pos, color, drawingShadows );
return;
}
VECTOR2I p0;
VECTOR2I dir;
int len = aPin->GetLength();
@ -933,10 +946,6 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
}
}
if( dangling )
drawPinDanglingSymbol( pos, drawingShadows );
LIB_SYMBOL* libEntry = aPin->GetParent();
// Draw the labels
@ -1190,11 +1199,15 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
// Draw the target (an open square) for a wire or label which has no connection or is
// being moved.
void SCH_PAINTER::drawDanglingSymbol( const wxPoint& aPos, int aWidth, bool aDrawingShadows )
void SCH_PAINTER::drawDanglingSymbol( const wxPoint& aPos, const COLOR4D& aColor, int aWidth,
bool aDrawingShadows )
{
wxPoint radius( aWidth + Mils2iu( DANGLING_SYMBOL_SIZE / 2 ),
aWidth + Mils2iu( DANGLING_SYMBOL_SIZE / 2 ) );
// Dangling symbols must be drawn in a slightly different colour so they can be seen when
// they overlap with a junction dot.
m_gal->SetStrokeColor( aColor.Brightened( 0.3 ) );
m_gal->SetIsStroke( true );
m_gal->SetIsFill( false );
m_gal->SetLineWidth( aDrawingShadows ? getShadowWidth()
@ -1238,6 +1251,23 @@ void SCH_PAINTER::draw( const SCH_LINE *aLine, int aLayer )
float width = getLineWidth( aLine, drawingShadows );
PLOT_DASH_TYPE lineStyle = aLine->GetEffectiveLineStyle();
if( aLayer == LAYER_DANGLING )
{
if( aLine->IsStartDangling() && aLine->IsWire() )
{
drawDanglingSymbol( aLine->GetStartPoint(), color,
getLineWidth( aLine, drawingShadows ), drawingShadows );
}
if( aLine->IsEndDangling() && aLine->IsWire() )
{
drawDanglingSymbol( aLine->GetEndPoint(), color,
getLineWidth( aLine, drawingShadows ), drawingShadows );
}
return;
}
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->SetLineWidth( width );
@ -1291,18 +1321,6 @@ void SCH_PAINTER::draw( const SCH_LINE *aLine, int aLayer )
start = next;
}
}
if( aLine->IsStartDangling() && aLine->IsWire() )
{
drawDanglingSymbol( aLine->GetStartPoint(), getLineWidth( aLine, drawingShadows ),
drawingShadows );
}
if( aLine->IsEndDangling() && aLine->IsWire() )
{
drawDanglingSymbol( aLine->GetEndPoint(), getLineWidth( aLine, drawingShadows ),
drawingShadows );
}
}
@ -1343,12 +1361,21 @@ void SCH_PAINTER::draw( const SCH_TEXT *aText, int aLayer )
return;
}
if( aLayer == LAYER_DANGLING )
{
if( aText->IsDangling() )
{
drawDanglingSymbol( aText->GetTextPos(), color, Mils2iu( DANGLING_SYMBOL_SIZE / 2 ),
drawingShadows );
}
return;
}
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getTextThickness( aText, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->SetTextAttributes( aText );
m_gal->SetFontUnderlined( false );
VECTOR2D text_offset = aText->GetTextPos() + aText->GetSchematicTextOffset( &m_schSettings );
wxString shownText( aText->GetShownText() );
@ -1379,15 +1406,11 @@ void SCH_PAINTER::draw( const SCH_TEXT *aText, int aLayer )
if( !shownText.IsEmpty() )
{
m_gal->SetTextAttributes( aText );
m_gal->SetFontUnderlined( false );
strokeText( shownText, text_offset, aText->GetTextAngleRadians() );
}
if( aText->IsDangling() )
{
drawDanglingSymbol( aText->GetTextPos(), Mils2iu( DANGLING_SYMBOL_SIZE / 2 ),
drawingShadows );
}
}
@ -1785,25 +1808,31 @@ void SCH_PAINTER::draw( const SCH_BUS_ENTRY_BASE *aEntry, int aLayer )
if( aEntry->Type() == SCH_BUS_BUS_ENTRY_T )
color = getRenderColor( aEntry, LAYER_BUS, drawingShadows );
line.SetLineColor( color );
line.SetLineStyle( aEntry->GetStrokeStyle() );
draw( &line, aLayer );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( drawingShadows ? getShadowWidth() : 1.0F );
if( aEntry->IsDanglingStart() )
if( aLayer == LAYER_DANGLING )
{
m_gal->DrawCircle( aEntry->GetPosition(),
aEntry->GetPenWidth() + ( TARGET_BUSENTRY_RADIUS / 2 ) );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color.Brightened( 0.3 ) );
m_gal->SetLineWidth( drawingShadows ? getShadowWidth() : 1.0F );
if( aEntry->IsDanglingStart() )
{
m_gal->DrawCircle( aEntry->GetPosition(),
aEntry->GetPenWidth() + ( TARGET_BUSENTRY_RADIUS / 2 ) );
}
if( aEntry->IsDanglingEnd() )
{
m_gal->DrawCircle( aEntry->GetEnd(),
aEntry->GetPenWidth() + ( TARGET_BUSENTRY_RADIUS / 2 ) );
}
}
if( aEntry->IsDanglingEnd() )
else
{
m_gal->DrawCircle( aEntry->GetEnd(),
aEntry->GetPenWidth() + ( TARGET_BUSENTRY_RADIUS / 2 ) );
line.SetLineColor( color );
line.SetLineStyle( aEntry->GetStrokeStyle() );
draw( &line, aLayer );
}
}

View File

@ -166,8 +166,10 @@ private:
void draw( const SCH_LINE* aLine, int aLayer );
void draw( const SCH_BUS_ENTRY_BASE* aEntry, int aLayer );
void drawPinDanglingSymbol( const VECTOR2I& aPos, bool aDrawingShadows );
void drawDanglingSymbol( const wxPoint& aPos, int aWidth, bool aDrawingShadows );
void drawPinDanglingSymbol( const VECTOR2I& aPos, const COLOR4D& aColor,
bool aDrawingShadows );
void drawDanglingSymbol( const wxPoint& aPos, const COLOR4D& aColor, int aWidth,
bool aDrawingShadows );
int internalPinDecoSize( const LIB_PIN &aPin );
int externalPinDecoSize( const LIB_PIN &aPin );

View File

@ -140,6 +140,15 @@ int SCH_PIN::GetLength() const
}
void SCH_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 3;
aLayers[0] = LAYER_DANGLING;
aLayers[1] = LAYER_DEVICE;
aLayers[2] = LAYER_SELECTION_SHADOWS;
}
bool SCH_PIN::Matches( const wxFindReplaceData& aSearchData, void* aAuxDat ) const
{
if( !( aSearchData.GetFlags() & FR_SEARCH_ALL_PINS ) )

View File

@ -64,6 +64,8 @@ public:
wxString GetAlt() const { return m_alt; }
void SetAlt( const wxString& aAlt ) { m_alt = aAlt; }
void ViewGetLayers( int aLayers[], int& aCount ) const override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;

View File

@ -919,6 +919,15 @@ const EDA_RECT SCH_LABEL::GetBoundingBox() const
}
void SCH_LABEL::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 3;
aLayers[0] = LAYER_DANGLING;
aLayers[1] = m_layer;
aLayers[2] = LAYER_SELECTION_SHADOWS;
}
wxString SCH_LABEL::GetSelectMenuText( EDA_UNITS aUnits ) const
{
return wxString::Format( _( "Label '%s'" ), ShortenedShownText() );

View File

@ -308,6 +308,8 @@ public:
( aItem->GetLayer() == LAYER_WIRE || aItem->GetLayer() == LAYER_BUS );
}
void ViewGetLayers( int aLayers[], int& aCount ) const override;
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
BITMAPS GetMenuImage() const override;

View File

@ -45,7 +45,7 @@ constexpr double SCH_WORLD_UNIT ( 1e-7 / 0.0254 );
static const LAYER_NUM SCH_LAYER_ORDER[] =
{
LAYER_GP_OVERLAY, LAYER_SELECT_OVERLAY,
LAYER_ERC_ERR, LAYER_ERC_WARN,
LAYER_ERC_ERR, LAYER_ERC_WARN, LAYER_DANGLING,
LAYER_REFERENCEPART, LAYER_VALUEPART, LAYER_FIELDS,
LAYER_BUS_JUNCTION, LAYER_JUNCTION, LAYER_NOCONNECT,
LAYER_HIERLABEL,

View File

@ -345,6 +345,7 @@ enum SCH_LAYER_ID: int
LAYER_SHEETFIELDS,
LAYER_SHEETLABEL,
LAYER_NOCONNECT,
LAYER_DANGLING,
LAYER_ERC_WARN,
LAYER_ERC_ERR,
LAYER_DEVICE_BACKGROUND,