7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-03-30 06:16:56 +00:00

De-duplicate table border drawing code.

Also cleans up a misconception about table header borders,
and renames the getter/setter to be clearer.

Also makes sure that table cells are updated when the table
layer changes.

And another bug where we were writing the grey color value
back to the cell for hidden cells.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20319
This commit is contained in:
Jeff Young 2025-03-13 12:26:17 +00:00
parent 5996cffabc
commit 93ea523eec
14 changed files with 147 additions and 289 deletions

View File

@ -323,7 +323,7 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags )
ret = hash_board_item( table, aFlags );
hash_combine( ret, table->StrokeExternal() );
hash_combine( ret, table->StrokeHeader() );
hash_combine( ret, table->StrokeHeaderSeparator() );
hash_combine( ret, table->StrokeColumns() );
hash_combine( ret, table->StrokeRows() );

View File

@ -188,7 +188,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
//
m_borderCheckbox->SetValue( m_table->StrokeExternal() );
m_headerBorder->SetValue( m_table->StrokeHeader() );
m_headerBorder->SetValue( m_table->StrokeHeaderSeparator() );
if( m_table->GetBorderStroke().GetWidth() >= 0 )
m_borderWidth.SetValue( m_table->GetBorderStroke().GetWidth() );
@ -202,11 +202,11 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
else
m_borderStyleCombo->SetSelection( 0 );
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderColorLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderColorSwatch->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderColorLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderColorSwatch->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
@ -344,7 +344,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
}
m_table->SetStrokeExternal( m_borderCheckbox->GetValue() );
m_table->SetStrokeHeader( m_headerBorder->GetValue() );
m_table->SetStrokeHeaderSeparator( m_headerBorder->GetValue() );
{
STROKE_PARAMS stroke = m_table->GetBorderStroke();

View File

@ -1392,9 +1392,9 @@ void SCH_IO_KICAD_SEXPR::saveTable( SCH_TABLE* aTable )
m_out->Print( "(border" );
KICAD_FORMAT::FormatBool( m_out, "external", aTable->StrokeExternal() );
KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeader() );
KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeaderSeparator() );
if( aTable->StrokeExternal() || aTable->StrokeHeader() )
if( aTable->StrokeExternal() || aTable->StrokeHeaderSeparator() )
aTable->GetBorderStroke().Format( m_out, schIUScale );
m_out->Print( ")" ); // Close `border` token.

View File

@ -4607,7 +4607,7 @@ SCH_TABLE* SCH_IO_KICAD_SEXPR_PARSER::parseSchTable()
break;
case T_header:
table->SetStrokeHeader( parseBool() );
table->SetStrokeHeaderSeparator( parseBool() );
NeedRIGHT();
break;

View File

@ -2199,7 +2199,7 @@ void SCH_PAINTER::draw( const SCH_TABLE* aTable, int aLayer, bool aDimmed )
setupStroke( aTable->GetBorderStroke() );
if( aTable->StrokeHeader() )
if( aTable->StrokeHeaderSeparator() )
{
if( !first->GetTextAngle().IsHorizontal() )
strokeLine( VECTOR2I( first->GetEndX(), pos.y ),

View File

@ -38,7 +38,7 @@
SCH_TABLE::SCH_TABLE( int aLineWidth ) :
SCH_ITEM( nullptr, SCH_TABLE_T ),
m_strokeExternal( true ),
m_strokeHeader( true ),
m_StrokeHeaderSeparator( true ),
m_borderStroke( aLineWidth, LINE_STYLE::DEFAULT, COLOR4D::UNSPECIFIED ),
m_strokeRows( true ),
m_strokeColumns( true ),
@ -53,7 +53,7 @@ SCH_TABLE::SCH_TABLE( const SCH_TABLE& aTable ) :
SCH_ITEM( aTable )
{
m_strokeExternal = aTable.m_strokeExternal;
m_strokeHeader = aTable.m_strokeHeader;
m_StrokeHeaderSeparator = aTable.m_StrokeHeaderSeparator;
m_borderStroke = aTable.m_borderStroke;
m_strokeRows = aTable.m_strokeRows;
m_strokeColumns = aTable.m_strokeColumns;
@ -86,7 +86,7 @@ void SCH_TABLE::SwapData( SCH_ITEM* aItem )
SCH_TABLE* table = static_cast<SCH_TABLE*>( aItem );
std::swap( m_strokeExternal, table->m_strokeExternal );
std::swap( m_strokeHeader, table->m_strokeHeader );
std::swap( m_StrokeHeaderSeparator, table->m_StrokeHeaderSeparator );
std::swap( m_borderStroke, table->m_borderStroke );
std::swap( m_strokeRows, table->m_strokeRows );
std::swap( m_strokeColumns, table->m_strokeColumns );
@ -425,7 +425,7 @@ void SCH_TABLE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS&
setupStroke( GetBorderStroke() );
SCH_TABLECELL* cell = GetCell( 0, 0 );
if( StrokeHeader() )
if( StrokeHeaderSeparator() )
{
if( !cell->GetTextAngle().IsHorizontal() )
{
@ -526,7 +526,7 @@ static struct SCH_TABLE_DESC
tableProps );
propMgr.AddProperty( new PROPERTY<SCH_TABLE, bool>( _HKI( "Header Border" ),
&SCH_TABLE::SetStrokeHeader, &SCH_TABLE::StrokeHeader ),
&SCH_TABLE::SetStrokeHeaderSeparator, &SCH_TABLE::StrokeHeaderSeparator ),
tableProps );
propMgr.AddProperty( new PROPERTY<SCH_TABLE, int>( _HKI( "Border Width" ),

View File

@ -53,8 +53,8 @@ public:
void SetStrokeExternal( bool aDoStroke ) { m_strokeExternal = aDoStroke; }
bool StrokeExternal() const { return m_strokeExternal; }
void SetStrokeHeader( bool aDoStroke ) { m_strokeHeader = aDoStroke; }
bool StrokeHeader() const { return m_strokeHeader; }
void SetStrokeHeaderSeparator( bool aDoStroke ) { m_StrokeHeaderSeparator = aDoStroke; }
bool StrokeHeaderSeparator() const { return m_StrokeHeaderSeparator; }
void SetBorderStroke( const STROKE_PARAMS& aParams ) { m_borderStroke = aParams; }
const STROKE_PARAMS& GetBorderStroke() const { return m_borderStroke; }
@ -238,7 +238,7 @@ public:
protected:
bool m_strokeExternal;
bool m_strokeHeader;
bool m_StrokeHeaderSeparator;
STROKE_PARAMS m_borderStroke;
bool m_strokeRows;
bool m_strokeColumns;

View File

@ -211,7 +211,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
m_cbLocked->SetValue( m_table->IsLocked() );
m_borderCheckbox->SetValue( m_table->StrokeExternal() );
m_headerBorder->SetValue( m_table->StrokeHeader() );
m_headerBorder->SetValue( m_table->StrokeHeaderSeparator() );
if( m_table->GetBorderStroke().GetWidth() >= 0 )
m_borderWidth.SetValue( m_table->GetBorderStroke().GetWidth() );
@ -223,9 +223,9 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataToWindow()
else
m_borderStyleCombo->SetSelection( 0 );
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
@ -339,6 +339,10 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
wxString txt = m_grid->GetCellValue( row, col );
// Don't insert grey colour value back in to table cell
if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
txt = wxEmptyString;
// convert any text variable cross-references to their UUIDs
txt = board->ConvertCrossReferencesToKIIDs( txt );
@ -353,6 +357,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
#endif
tableCell->SetText( txt );
tableCell->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );
}
}
@ -360,7 +365,7 @@ bool DIALOG_TABLE_PROPERTIES::TransferDataFromWindow()
m_table->SetLocked( m_cbLocked->GetValue() );
m_table->SetStrokeExternal( m_borderCheckbox->GetValue() );
m_table->SetStrokeHeader( m_headerBorder->GetValue() );
m_table->SetStrokeHeaderSeparator( m_headerBorder->GetValue() );
{
STROKE_PARAMS stroke = m_table->GetBorderStroke();

View File

@ -2129,9 +2129,9 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TABLE* aTable ) const
m_out->Print( "(border" );
KICAD_FORMAT::FormatBool( m_out, "external", aTable->StrokeExternal() );
KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeader() );
KICAD_FORMAT::FormatBool( m_out, "header", aTable->StrokeHeaderSeparator() );
if( aTable->StrokeExternal() || aTable->StrokeHeader() )
if( aTable->StrokeExternal() || aTable->StrokeHeaderSeparator() )
aTable->GetBorderStroke().Format( m_out, pcbIUScale );
m_out->Print( ")" ); // Close `border` token.

View File

@ -3932,7 +3932,7 @@ PCB_TABLE* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TABLE( BOARD_ITEM* aParent )
break;
case T_header:
table->SetStrokeHeader( parseBool() );
table->SetStrokeHeaderSeparator( parseBool() );
NeedRIGHT();
break;

View File

@ -2481,43 +2481,26 @@ void PCB_PAINTER::draw( const PCB_TABLE* aTable, int aLayer )
return;
for( PCB_TABLECELL* cell : aTable->GetCells() )
draw( static_cast<PCB_TEXTBOX*>( cell ), aLayer );
{
if( cell->GetColSpan() > 0 || cell->GetRowSpan() > 0 )
draw( static_cast<PCB_TEXTBOX*>( cell ), aLayer );
}
// Selection for tables is done with a background wash, so pass in nullptr to GetColor()
// so we just get the "normal" (un-selected/un-brightened) color for the borders.
COLOR4D color = m_pcbSettings.GetColor( nullptr, aLayer );
int lineWidth;
LINE_STYLE lineStyle;
COLOR4D color = m_pcbSettings.GetColor( nullptr, aLayer );
auto setupStroke =
[&]( const STROKE_PARAMS& stroke )
aTable->DrawBorders(
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
{
lineWidth = getLineThickness( stroke.GetWidth() );
lineStyle = stroke.GetLineStyle();
int lineWidth = getLineThickness( stroke.GetWidth() );
LINE_STYLE lineStyle = stroke.GetLineStyle();
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->SetLineWidth( lineWidth );
};
auto strokeShape =
[&]( const SHAPE& shape )
{
STROKE_PARAMS::Stroke( &shape, lineStyle, lineWidth, &m_pcbSettings,
[&]( VECTOR2I a, VECTOR2I b )
{
// DrawLine has problem with 0 length lines so enforce minimum
if( a == b )
m_gal->DrawLine( a+1, b );
else
m_gal->DrawLine( a, b );
} );
};
auto strokeLine =
[&]( VECTOR2I ptA, VECTOR2I ptB )
{
if( lineStyle <= LINE_STYLE::FIRST_TYPE )
{
m_gal->DrawLine( ptA, ptB );
@ -2525,80 +2508,18 @@ void PCB_PAINTER::draw( const PCB_TABLE* aTable, int aLayer )
else
{
SHAPE_SEGMENT seg( ptA, ptB );
strokeShape( seg );
STROKE_PARAMS::Stroke( &seg, lineStyle, lineWidth, &m_pcbSettings,
[&]( VECTOR2I a, VECTOR2I b )
{
// DrawLine has problem with 0 length lines so enforce minimum
if( a == b )
m_gal->DrawLine( a+1, b );
else
m_gal->DrawLine( a, b );
} );
}
};
if( aTable->GetSeparatorsStroke().GetWidth() >= 0 )
{
setupStroke( aTable->GetSeparatorsStroke() );
// Stroke column edges
if( aTable->StrokeColumns() )
{
for( int col = 0; col < aTable->GetColCount() - 1; ++col )
{
int row = aTable->StrokeHeader() ? 0 : 1;
for( ; row < aTable->GetRowCount(); ++row )
{
PCB_TABLECELL* cell = aTable->GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
{
// Draw right edge (between adjacent cells)
strokeLine( corners[1], corners[2] );
}
}
}
}
// Stroke row edges
if( aTable->StrokeRows() )
{
for( int row = 0; row < aTable->GetRowCount() - 1; ++row )
{
for( int col = 0; col < aTable->GetColCount(); ++col )
{
PCB_TABLECELL* cell = aTable->GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
{
// Draw bottom edge (between adjacent cells)
strokeLine( corners[2], corners[3] );
}
}
}
}
}
if( aTable->GetBorderStroke().GetWidth() >= 0 )
{
setupStroke( aTable->GetBorderStroke() );
std::vector<VECTOR2I> topLeft = aTable->GetCell( 0, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomLeft = aTable->GetCell( aTable->GetRowCount() - 1, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> topRight = aTable->GetCell( 0, aTable->GetColCount() - 1 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomRight = aTable->GetCell( aTable->GetRowCount() - 1, aTable->GetColCount() - 1 )->GetCornersInSequence();
if( aTable->StrokeHeader() )
{
strokeLine( topLeft[0], topRight[1] );
strokeLine( topLeft[0], topLeft[3] );
strokeLine( topLeft[3], topRight[2] );
strokeLine( topRight[1], topRight[2] );
}
if( aTable->StrokeExternal() )
{
strokeLine( topLeft[3], topRight[2] );
strokeLine( topRight[2], bottomRight[2] );
strokeLine( bottomRight[2], bottomLeft[3] );
strokeLine( bottomLeft[3], topLeft[3] );
}
}
} );
// Highlight selected tablecells with a background wash.
for( PCB_TABLECELL* cell : aTable->GetCells() )

View File

@ -33,7 +33,7 @@
PCB_TABLE::PCB_TABLE( BOARD_ITEM* aParent, int aLineWidth ) :
BOARD_ITEM_CONTAINER( aParent, PCB_TABLE_T ),
m_strokeExternal( true ),
m_strokeHeader( true ),
m_StrokeHeaderSeparator( true ),
m_borderStroke( aLineWidth, LINE_STYLE::DEFAULT, COLOR4D::UNSPECIFIED ),
m_strokeRows( true ),
m_strokeColumns( true ),
@ -47,7 +47,7 @@ PCB_TABLE::PCB_TABLE( const PCB_TABLE& aTable ) :
BOARD_ITEM_CONTAINER( aTable )
{
m_strokeExternal = aTable.m_strokeExternal;
m_strokeHeader = aTable.m_strokeHeader;
m_StrokeHeaderSeparator = aTable.m_StrokeHeaderSeparator;
m_borderStroke = aTable.m_borderStroke;
m_strokeRows = aTable.m_strokeRows;
m_strokeColumns = aTable.m_strokeColumns;
@ -81,7 +81,7 @@ void PCB_TABLE::swapData( BOARD_ITEM* aImage )
std::swap( m_isLocked, table->m_isLocked );
std::swap( m_strokeExternal, table->m_strokeExternal );
std::swap( m_strokeHeader, table->m_strokeHeader );
std::swap( m_StrokeHeaderSeparator, table->m_StrokeHeaderSeparator );
std::swap( m_borderStroke, table->m_borderStroke );
std::swap( m_strokeRows, table->m_strokeRows );
std::swap( m_strokeColumns, table->m_strokeColumns );
@ -236,6 +236,70 @@ const BOX2I PCB_TABLE::GetBoundingBox() const
}
void PCB_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1,
const VECTOR2I& aPt2,
const STROKE_PARAMS& aStroke )>& aCallback ) const
{
std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomLeft = GetCell( GetRowCount() - 1, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> topRight = GetCell( 0, GetColCount() - 1 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomRight = GetCell( GetRowCount() - 1, GetColCount() - 1 )->GetCornersInSequence();
STROKE_PARAMS stroke;
for( int col = 0; col < GetColCount() - 1; ++col )
{
if( StrokeColumns() )
stroke = GetSeparatorsStroke();
else
continue;
for( int row = 0; row < GetRowCount(); ++row )
{
PCB_TABLECELL* cell = GetCell( row, col );
if( cell->GetColSpan() == 0 )
continue;
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
aCallback( corners[1], corners[2], stroke );
}
}
for( int row = 0; row < GetRowCount() - 1; ++row )
{
if( row == 0 && StrokeHeaderSeparator() )
stroke = GetBorderStroke();
else if( StrokeRows() )
stroke = GetSeparatorsStroke();
else
continue;
for( int col = 0; col < GetColCount(); ++col )
{
PCB_TABLECELL* cell = GetCell( row, col );
if( cell->GetRowSpan() == 0 )
continue;
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
aCallback( corners[2], corners[3], stroke );
}
}
if( StrokeExternal() && GetBorderStroke().GetWidth() >= 0 )
{
aCallback( topLeft[0], topRight[1], GetBorderStroke() );
aCallback( topRight[1], bottomRight[2], GetBorderStroke() );
aCallback( bottomRight[2], bottomLeft[3], GetBorderStroke() );
aCallback( bottomLeft[3], topLeft[0], GetBorderStroke() );
}
}
std::shared_ptr<SHAPE> PCB_TABLE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
{
std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence();
@ -254,59 +318,11 @@ std::shared_ptr<SHAPE> PCB_TABLE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHI
shape->AddShape( new SHAPE_SIMPLE( pts ) );
auto addSeg =
[&shape]( const VECTOR2I& ptA, const VECTOR2I& ptB, int width )
DrawBorders(
[&shape]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
{
shape->AddShape( new SHAPE_SEGMENT( ptA, ptB, width ) );
};
if( StrokeColumns() && GetSeparatorsStroke().GetWidth() >= 0)
{
for( int col = 0; col < GetColCount() - 1; ++col )
{
int row = StrokeHeader() ? 0 : 1;
for( ; row < GetRowCount(); ++row )
{
PCB_TABLECELL* cell = GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
addSeg( corners[1], corners[2], GetSeparatorsStroke().GetWidth() );
}
}
}
if( StrokeRows() && GetSeparatorsStroke().GetWidth() >= 0 )
{
for( int row = 0; row < GetRowCount() - 1; ++row )
{
for( int col = 0; col < GetColCount(); ++col )
{
PCB_TABLECELL* cell = GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
addSeg( corners[2], corners[3], GetSeparatorsStroke().GetWidth() );
}
}
}
if( StrokeHeader() && GetBorderStroke().GetWidth() >= 0 )
{
addSeg( topLeft[0], topRight[1], GetBorderStroke().GetWidth() );
addSeg( topLeft[0], topLeft[3], GetBorderStroke().GetWidth() );
addSeg( topLeft[3], topRight[2], GetBorderStroke().GetWidth() );
addSeg( topRight[1], topRight[2], GetBorderStroke().GetWidth() );
}
if( StrokeExternal() && GetBorderStroke().GetWidth() >= 0 )
{
addSeg( topLeft[3], topRight[2], GetBorderStroke().GetWidth() );
addSeg( topRight[2], bottomRight[2], GetBorderStroke().GetWidth() );
addSeg( bottomRight[2], bottomLeft[3], GetBorderStroke().GetWidth() );
addSeg( bottomLeft[3], topLeft[3], GetBorderStroke().GetWidth() );
}
shape->AddShape( new SHAPE_SEGMENT( ptA, ptB, stroke.GetWidth() ) );
} );
return shape;
}
@ -321,7 +337,7 @@ void PCB_TABLE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID a
if( StrokeColumns() || StrokeRows() )
gap = std::max( gap, aClearance + GetSeparatorsStroke().GetWidth() / 2 );
if( StrokeExternal() || StrokeHeader() )
if( StrokeExternal() || StrokeHeaderSeparator() )
gap = std::max( gap, aClearance + GetBorderStroke().GetWidth() / 2 );
for( PCB_TABLECELL* cell : m_cells )
@ -456,7 +472,7 @@ bool PCB_TABLE::operator==( const PCB_TABLE& aOther ) const
if( m_strokeExternal != aOther.m_strokeExternal )
return false;
if( m_strokeHeader != aOther.m_strokeHeader )
if( m_StrokeHeaderSeparator != aOther.m_StrokeHeaderSeparator )
return false;
if( m_borderStroke != aOther.m_borderStroke )
@ -502,7 +518,7 @@ double PCB_TABLE::Similarity( const BOARD_ITEM& aOther ) const
if( m_strokeExternal != other.m_strokeExternal )
similarity *= 0.9;
if( m_strokeHeader != other.m_strokeHeader )
if( m_StrokeHeaderSeparator != other.m_StrokeHeaderSeparator )
similarity *= 0.9;
if( m_borderStroke != other.m_borderStroke )
@ -567,7 +583,7 @@ static struct PCB_TABLE_DESC
tableProps );
propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "Header Border" ),
&PCB_TABLE::SetStrokeHeader, &PCB_TABLE::StrokeHeader ),
&PCB_TABLE::SetStrokeHeaderSeparator, &PCB_TABLE::StrokeHeaderSeparator ),
tableProps );
propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Border Width" ),

View File

@ -52,8 +52,8 @@ public:
void SetStrokeExternal( bool aDoStroke ) { m_strokeExternal = aDoStroke; }
bool StrokeExternal() const { return m_strokeExternal; }
void SetStrokeHeader( bool aDoStroke ) { m_strokeHeader = aDoStroke; }
bool StrokeHeader() const { return m_strokeHeader; }
void SetStrokeHeaderSeparator( bool aDoStroke ) { m_StrokeHeaderSeparator = aDoStroke; }
bool StrokeHeaderSeparator() const { return m_StrokeHeaderSeparator; }
void SetBorderStroke( const STROKE_PARAMS& aParams ) { m_borderStroke = aParams; }
const STROKE_PARAMS& GetBorderStroke() const { return m_borderStroke; }
@ -204,6 +204,10 @@ public:
const BOX2I GetBoundingBox() const override;
void DrawBorders( const std::function<void( const VECTOR2I& aPt1,
const VECTOR2I& aPt2,
const STROKE_PARAMS& aStroke )>& aCallback ) const;
// @copydoc BOARD_ITEM::GetEffectiveShape
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
FLASHING aFlash = FLASHING::DEFAULT ) const override;
@ -252,7 +256,7 @@ protected:
protected:
bool m_strokeExternal;
bool m_strokeHeader;
bool m_StrokeHeaderSeparator;
STROKE_PARAMS m_borderStroke;
bool m_strokeRows;
bool m_strokeColumns;

View File

@ -1122,8 +1122,6 @@ void BRDITEMS_PLOTTER::PlotTableBorders( const PCB_TABLE* aTable )
if( !m_layerMask[aTable->GetLayer()] )
return;
int lineWidth;
LINE_STYLE lineStyle;
GBR_METADATA gbr_metadata;
if( const FOOTPRINT* parentFP = aTable->GetParentFootprint() )
@ -1132,27 +1130,12 @@ void BRDITEMS_PLOTTER::PlotTableBorders( const PCB_TABLE* aTable )
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP );
}
auto setupStroke =
[&]( const STROKE_PARAMS& stroke )
aTable->DrawBorders(
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
{
lineWidth = stroke.GetWidth();
lineStyle = stroke.GetLineStyle();
};
int lineWidth = stroke.GetWidth();
LINE_STYLE lineStyle = stroke.GetLineStyle();
auto strokeShape =
[&]( const SHAPE& shape )
{
STROKE_PARAMS::Stroke( &shape, lineStyle, lineWidth, m_plotter->RenderSettings(),
[&]( const VECTOR2I& a, const VECTOR2I& b )
{
m_plotter->ThickSegment( a, b, lineWidth, GetPlotMode(),
&gbr_metadata );
} );
};
auto strokeLine =
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB )
{
if( lineStyle <= LINE_STYLE::FIRST_TYPE )
{
m_plotter->ThickSegment( ptA, ptB, lineWidth, GetPlotMode(), &gbr_metadata );
@ -1160,86 +1143,15 @@ void BRDITEMS_PLOTTER::PlotTableBorders( const PCB_TABLE* aTable )
else
{
SHAPE_SEGMENT seg( ptA, ptB );
strokeShape( seg );
STROKE_PARAMS::Stroke( &seg, lineStyle, lineWidth, m_plotter->RenderSettings(),
[&]( const VECTOR2I& a, const VECTOR2I& b )
{
m_plotter->ThickSegment( a, b, lineWidth, GetPlotMode(),
&gbr_metadata );
} );
}
};
if( aTable->GetSeparatorsStroke().GetWidth() >= 0 )
{
setupStroke( aTable->GetSeparatorsStroke() );
if( aTable->StrokeColumns() )
{
for( int col = 0; col < aTable->GetColCount() - 1; ++col )
{
int row = 1;
if( aTable->StrokeHeader() )
{
row = 0;
}
for( ; row < aTable->GetRowCount(); ++row )
{
PCB_TABLECELL* cell = aTable->GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
{
// Draw right edge (between adjacent cells)
strokeLine( corners[1], corners[2] );
}
}
}
}
if( aTable->StrokeRows() )
{
for( int row = 0; row < aTable->GetRowCount() - 1; ++row )
{
for( int col = 0; col < aTable->GetColCount(); ++col )
{
PCB_TABLECELL* cell = aTable->GetCell( row, col );
std::vector<VECTOR2I> corners = cell->GetCornersInSequence();
if( corners.size() == 4 )
{
// Draw bottom edge (between adjacent cells)
strokeLine( corners[2], corners[3] );
}
}
}
}
}
if( aTable->GetBorderStroke().GetWidth() >= 0 )
{
setupStroke( aTable->GetBorderStroke() );
std::vector<VECTOR2I> topLeft = aTable->GetCell( 0, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomLeft =
aTable->GetCell( aTable->GetRowCount() - 1, 0 )->GetCornersInSequence();
std::vector<VECTOR2I> topRight =
aTable->GetCell( 0, aTable->GetColCount() - 1 )->GetCornersInSequence();
std::vector<VECTOR2I> bottomRight =
aTable->GetCell( aTable->GetRowCount() - 1, aTable->GetColCount() - 1 )
->GetCornersInSequence();
if( aTable->StrokeHeader() )
{
strokeLine( topLeft[0], topRight[1] );
strokeLine( topLeft[0], topLeft[3] );
strokeLine( topLeft[3], topRight[2] );
strokeLine( topRight[1], topRight[2] );
}
if( aTable->StrokeExternal() )
{
strokeLine( topLeft[3], topRight[2] );
strokeLine( topRight[2], bottomRight[2] );
strokeLine( bottomRight[2], bottomLeft[3] );
strokeLine( bottomLeft[3], topLeft[3] );
}
}
} );
}