KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_table.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <pcb_edit_frame.h>
25#include <footprint.h>
26#include <pcb_table.h>
27#include <board.h>
33#include <pcb_painter.h> // for PCB_RENDER_SETTINGS
34#include <properties/property.h>
36
37
38PCB_TABLE::PCB_TABLE( BOARD_ITEM* aParent, int aLineWidth ) :
40 m_strokeExternal( true ),
43 m_strokeRows( true ),
44 m_strokeColumns( true ),
46 m_colCount( 0 )
47{
48}
49
50
68
69
71{
72 // We own our cells; delete them
73 for( PCB_TABLECELL* cell : m_cells )
74 delete cell;
75}
76
77
79{
80 wxCHECK_RET( aImage != nullptr && aImage->Type() == PCB_TABLE_T, wxT( "Cannot swap data with invalid table." ) );
81
82 PCB_TABLE* table = static_cast<PCB_TABLE*>( aImage );
83
84 std::swap( m_layer, table->m_layer );
85 std::swap( m_isLocked, table->m_isLocked );
86
87 std::swap( m_strokeExternal, table->m_strokeExternal );
88 std::swap( m_StrokeHeaderSeparator, table->m_StrokeHeaderSeparator );
89 std::swap( m_borderStroke, table->m_borderStroke );
90 std::swap( m_strokeRows, table->m_strokeRows );
91 std::swap( m_strokeColumns, table->m_strokeColumns );
92 std::swap( m_separatorsStroke, table->m_separatorsStroke );
93
94 std::swap( m_colCount, table->m_colCount );
95 std::swap( m_colWidths, table->m_colWidths );
96 std::swap( m_rowHeights, table->m_rowHeights );
97
98 std::swap( m_cells, table->m_cells );
99
100 for( PCB_TABLECELL* cell : m_cells )
101 cell->SetParent( this );
102
103 for( PCB_TABLECELL* cell : table->m_cells )
104 cell->SetParent( table );
105}
106
107
109{
110 m_layer = aLayer;
111
112 for( PCB_TABLECELL* cell : m_cells )
113 cell->SetLayer( aLayer );
114}
115
116
118{
119 Move( aPos - GetPosition() );
120}
121
122
124{
125 if( m_cells.empty() )
126 return VECTOR2I( 0, 0 ); // Return origin if table has no cells
127
128 return m_cells[0]->GetPosition();
129}
130
131
133{
134 VECTOR2I tableSize;
135
136 for( int ii = 0; ii < GetColCount(); ++ii )
137 tableSize.x += GetColWidth( ii );
138
139 for( int ii = 0; ii < GetRowCount(); ++ii )
140 tableSize.y += GetRowHeight( ii );
141
142 return GetPosition() + tableSize;
143}
144
145
147{
148 if( m_cells.empty() )
149 return;
150
151 EDA_ANGLE cellAngle = m_cells[0]->GetTextAngle();
152
153 BOX2I cell0BBox = m_cells[0]->GetBoundingBox();
154 VECTOR2I stableCenter = cell0BBox.GetCenter();
155
156 int cell0Width = m_colWidths[0];
157 int cell0Height = m_rowHeights[0];
158
159 if( m_cells[0]->GetColSpan() > 1 )
160 {
161 for( int ii = 1; ii < m_cells[0]->GetColSpan(); ++ii )
162 cell0Width += m_colWidths[ii];
163 }
164
165 if( m_cells[0]->GetRowSpan() > 1 )
166 {
167 for( int ii = 1; ii < m_cells[0]->GetRowSpan(); ++ii )
168 cell0Height += m_rowHeights[ii];
169 }
170
171 VECTOR2I localCell0Center( cell0Width / 2, cell0Height / 2 );
172 RotatePoint( localCell0Center, cellAngle );
173
174 if( cellAngle != ANGLE_0 )
175 {
176 for( PCB_TABLECELL* cell : m_cells )
177 cell->Rotate( stableCenter, -cellAngle );
178 }
179
180 VECTOR2I unrotatedOrigin = stableCenter - VECTOR2I( cell0Width / 2, cell0Height / 2 );
181
182 int y = unrotatedOrigin.y;
183
184 for( int row = 0; row < GetRowCount(); ++row )
185 {
186 int x = unrotatedOrigin.x;
187 int rowHeight = m_rowHeights[row];
188
189 for( int col = 0; col < GetColCount(); ++col )
190 {
191 int colWidth = m_colWidths[col];
192
193 PCB_TABLECELL* cell = GetCell( row, col );
194
195 if( !cell )
196 continue;
197
198 int cellWidth = colWidth;
199 int cellHeight = rowHeight;
200
201 if( cell->GetColSpan() > 1 || cell->GetRowSpan() > 1 )
202 {
203 for( int ii = col + 1; ii < col + cell->GetColSpan(); ++ii )
204 cellWidth += m_colWidths[ii];
205
206 for( int ii = row + 1; ii < row + cell->GetRowSpan(); ++ii )
207 cellHeight += m_rowHeights[ii];
208 }
209
210 VECTOR2I pos( x, y );
211 VECTOR2I end( x + cellWidth, y + cellHeight );
212
213 if( cell->GetPosition() != pos )
214 {
215 cell->SetPosition( pos );
216 cell->ClearRenderCache();
217 }
218
219 if( cell->GetEnd() != end )
220 {
221 cell->SetEnd( end );
222 cell->ClearRenderCache();
223 }
224
225 x += colWidth;
226 }
227
228 y += rowHeight;
229 }
230
231 if( cellAngle != ANGLE_0 )
232 {
233 for( PCB_TABLECELL* cell : m_cells )
234 cell->Rotate( stableCenter, cellAngle );
235 }
236
237 BOX2I newCell0BBox = m_cells[0]->GetBoundingBox();
238 VECTOR2I newCenter = newCell0BBox.GetCenter();
239
240 if( newCenter != stableCenter )
241 {
242 VECTOR2I correction = stableCenter - newCenter;
243
244 for( PCB_TABLECELL* cell : m_cells )
245 cell->Move( correction );
246 }
247}
248
249
251{
252 std::vector<std::vector<BOX2I>> extents;
253
254 for( int row = 0; row < GetRowCount(); ++row )
255 {
256 extents.push_back( std::vector<BOX2I>() );
257
258 for( int col = 0; col < GetColCount(); ++col )
259 {
260 SHAPE_POLY_SET textPoly;
261 GetCell( row, col )->TransformTextToPolySet( textPoly, 0, ARC_LOW_DEF, ERROR_INSIDE );
262 extents[row].push_back( textPoly.BBox() );
263 }
264 }
265
266 for( int col = 0; col < GetColCount(); ++col )
267 {
268 int colWidth = 0;
269
270 for( int row = 0; row < GetRowCount(); ++row )
271 {
272 PCB_TABLECELL* cell = GetCell( row, col );
273 int margins = cell->GetMarginLeft() + cell->GetMarginRight();
274 colWidth = std::max<int>( colWidth, extents[row][col].GetWidth() + ( margins * 1.5 ) );
275 }
276
277 SetColWidth( col, colWidth );
278 }
279
280 for( int row = 0; row < GetRowCount(); ++row )
281 {
282 int rowHeight = 0;
283
284 for( int col = 0; col < GetColCount(); ++col )
285 {
286 PCB_TABLECELL* cell = GetCell( row, col );
287 int margins = cell->GetMarginLeft() + cell->GetMarginRight();
288 rowHeight = std::max( rowHeight, (int) extents[row][col].GetHeight() + margins );
289 }
290
291 SetRowHeight( row, rowHeight );
292 }
293
294 Normalize();
295}
296
297
298void PCB_TABLE::Move( const VECTOR2I& aMoveVector )
299{
300 for( PCB_TABLECELL* cell : m_cells )
301 cell->Move( aMoveVector );
302}
303
304
305void PCB_TABLE::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
306{
307 if( GetCells().empty() )
308 return;
309
310 for( PCB_TABLECELL* cell : m_cells )
311 cell->Rotate( aRotCentre, aAngle );
312
313 Normalize();
314}
315
316
317void PCB_TABLE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
318{
319 BOX2I originalBBox = GetBoundingBox();
320
321 VECTOR2I targetPos;
322
323 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
324 {
325 targetPos.x = 2 * aCentre.x - originalBBox.GetRight();
326 targetPos.y = originalBBox.GetTop();
327 }
328 else
329 {
330 targetPos.x = originalBBox.GetLeft();
331 targetPos.y = 2 * aCentre.y - originalBBox.GetBottom();
332 }
333
334 EDA_ANGLE originalAngle = m_cells[0]->GetTextAngle();
335
336 if( originalAngle != ANGLE_0 )
337 Rotate( GetPosition(), -originalAngle );
338
339 VECTOR2I tableOrigin = GetPosition();
340
341 for( PCB_TABLECELL* cell : m_cells )
342 cell->Flip( tableOrigin, aFlipDirection );
343
344 std::vector<PCB_TABLECELL*> oldCells = m_cells;
345
346 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
347 {
348 int rowOffset = 0;
349
350 for( int row = 0; row < GetRowCount(); ++row )
351 {
352 for( int col = 0; col < GetColCount(); ++col )
353 m_cells[rowOffset + col] = oldCells[rowOffset + GetColCount() - 1 - col];
354
355 rowOffset += GetColCount();
356 }
357
358 std::map<int, int> newColWidths;
359
360 for( int col = 0; col < GetColCount(); ++col )
361 newColWidths[col] = m_colWidths[GetColCount() - 1 - col];
362
363 m_colWidths = std::move( newColWidths );
364 }
365 else // TOP_BOTTOM
366 {
367 for( int row = 0; row < GetRowCount(); ++row )
368 {
369 for( int col = 0; col < GetColCount(); ++col )
370 {
371 int oldRow = GetRowCount() - 1 - row;
372 m_cells[row * GetColCount() + col] = oldCells[oldRow * GetColCount() + col];
373 }
374 }
375
376 std::map<int, int> newRowHeights;
377
378 for( int row = 0; row < GetRowCount(); ++row )
379 newRowHeights[row] = m_rowHeights[GetRowCount() - 1 - row];
380
381 m_rowHeights = std::move( newRowHeights );
382 }
383
385 Normalize();
386
387 if( originalAngle != ANGLE_0 )
388 Rotate( GetPosition(), originalAngle );
389
390 BOX2I newBBox = GetBoundingBox();
391 Move( targetPos - newBBox.GetPosition() );
392
393 int localWidth = 0;
394 for( int col = 0; col < GetColCount(); ++col )
395 localWidth += m_colWidths[col];
396
397 int localHeight = 0;
398 for( int row = 0; row < GetRowCount(); ++row )
399 localHeight += m_rowHeights[row];
400
401 bool isNowOnFrontSide = IsFrontLayer( GetLayer() );
402
403 VECTOR2I translation( 0, 0 );
404
405 if( aFlipDirection == FLIP_DIRECTION::TOP_BOTTOM )
406 {
407 translation.y = -localHeight;
408 }
409 else // LEFT_RIGHT
410 {
411 if( isNowOnFrontSide )
412 translation.x = localWidth;
413 else
414 translation.x = -localWidth;
415 }
416
417 RotatePoint( translation, originalAngle );
418
419 Move( translation );
420}
421
422
423void PCB_TABLE::RunOnChildren( const std::function<void( BOARD_ITEM* )>& aFunction, RECURSE_MODE aMode ) const
424{
425 for( PCB_TABLECELL* cell : m_cells )
426 {
427 aFunction( cell );
428
429 if( aMode == RECURSE_MODE::RECURSE )
430 cell->RunOnChildren( aFunction, aMode );
431 }
432}
433
434
436{
437 // Note: a table with no cells is not allowed
438 BOX2I bbox = m_cells[0]->GetBoundingBox();
439
440 bbox.Merge( m_cells[m_cells.size() - 1]->GetBoundingBox() );
441
442 return bbox;
443}
444
445
446void PCB_TABLE::DrawBorders( const std::function<void( const VECTOR2I& aPt1, const VECTOR2I& aPt2,
447 const STROKE_PARAMS& aStroke )>& aCallback ) const
448{
449 EDA_ANGLE drawAngle = GetCell( 0, 0 )->GetDrawRotation();
450 std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence( drawAngle );
451 std::vector<VECTOR2I> bottomLeft = GetCell( GetRowCount() - 1, 0 )->GetCornersInSequence( drawAngle );
452 std::vector<VECTOR2I> topRight = GetCell( 0, GetColCount() - 1 )->GetCornersInSequence( drawAngle );
453 std::vector<VECTOR2I> bottomRight =
454 GetCell( GetRowCount() - 1, GetColCount() - 1 )->GetCornersInSequence( drawAngle );
455 STROKE_PARAMS stroke;
456
457 for( int col = 0; col < GetColCount() - 1; ++col )
458 {
459 for( int row = 0; row < GetRowCount(); ++row )
460 {
461 if( row == 0 && StrokeHeaderSeparator() )
462 stroke = GetBorderStroke();
463 else if( StrokeColumns() )
464 stroke = GetSeparatorsStroke();
465 else
466 continue;
467
468 PCB_TABLECELL* cell = GetCell( row, col );
469
470 if( cell->GetColSpan() == 0 )
471 continue;
472
473 if( col + cell->GetColSpan() == GetColCount() )
474 continue;
475
476 std::vector<VECTOR2I> corners = cell->GetCornersInSequence( drawAngle );
477
478 if( corners.size() == 4 )
479 aCallback( corners[1], corners[2], stroke );
480 }
481 }
482
483 for( int row = 0; row < GetRowCount() - 1; ++row )
484 {
485 if( row == 0 && StrokeHeaderSeparator() )
486 stroke = GetBorderStroke();
487 else if( StrokeRows() )
488 stroke = GetSeparatorsStroke();
489 else
490 continue;
491
492 for( int col = 0; col < GetColCount(); ++col )
493 {
494 PCB_TABLECELL* cell = GetCell( row, col );
495
496 if( cell->GetRowSpan() == 0 )
497 continue;
498
499 if( row + cell->GetRowSpan() == GetRowCount() )
500 continue;
501
502 std::vector<VECTOR2I> corners = cell->GetCornersInSequence( drawAngle );
503
504 if( corners.size() == 4 )
505 aCallback( corners[2], corners[3], stroke );
506 }
507 }
508
509 if( StrokeExternal() && GetBorderStroke().GetWidth() >= 0 )
510 {
511 aCallback( topLeft[0], topRight[1], GetBorderStroke() );
512 aCallback( topRight[1], bottomRight[2], GetBorderStroke() );
513 aCallback( bottomRight[2], bottomLeft[3], GetBorderStroke() );
514 aCallback( bottomLeft[3], topLeft[0], GetBorderStroke() );
515 }
516}
517
518
519std::shared_ptr<SHAPE> PCB_TABLE::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
520{
521 EDA_ANGLE angle = GetCell( 0, 0 )->GetDrawRotation();
522 std::vector<VECTOR2I> topLeft = GetCell( 0, 0 )->GetCornersInSequence( angle );
523 std::vector<VECTOR2I> bottomLeft = GetCell( GetRowCount() - 1, 0 )->GetCornersInSequence( angle );
524 std::vector<VECTOR2I> topRight = GetCell( 0, GetColCount() - 1 )->GetCornersInSequence( angle );
525 std::vector<VECTOR2I> bottomRight = GetCell( GetRowCount() - 1, GetColCount() - 1 )->GetCornersInSequence( angle );
526
527 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
528
529 std::vector<VECTOR2I> pts;
530
531 pts.emplace_back( topLeft[3] );
532 pts.emplace_back( topRight[2] );
533 pts.emplace_back( bottomRight[2] );
534 pts.emplace_back( bottomLeft[3] );
535
536 shape->AddShape( new SHAPE_SIMPLE( pts ) );
537
539 [&shape]( const VECTOR2I& ptA, const VECTOR2I& ptB, const STROKE_PARAMS& stroke )
540 {
541 shape->AddShape( new SHAPE_SEGMENT( ptA, ptB, stroke.GetWidth() ) );
542 } );
543
544 return shape;
545}
546
547
548void PCB_TABLE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError,
549 ERROR_LOC aErrorLoc, bool aIgnoreLineWidth ) const
550{
551 int gap = aClearance;
552
553 if( StrokeColumns() || StrokeRows() )
554 gap = std::max( gap, aClearance + GetSeparatorsStroke().GetWidth() / 2 );
555
557 gap = std::max( gap, aClearance + GetBorderStroke().GetWidth() / 2 );
558
559 for( PCB_TABLECELL* cell : m_cells )
560 cell->TransformShapeToPolygon( aBuffer, aLayer, gap, aMaxError, aErrorLoc, false );
561}
562
563
565 KIGFX::RENDER_SETTINGS* aRenderSettings ) const
566{
567 // Convert graphic items (segments and texts) to a set of polygonal shapes
568 // aRenderSettings is used to draw lines when line style != LINE_STYLE::SOLID, so
569 // if nullptr line style will be ignored
571 [&aBuffer, aMaxError, aErrorLoc, aRenderSettings]( const VECTOR2I& ptA, const VECTOR2I& ptB,
572 const STROKE_PARAMS& stroke )
573 {
574 int lineWidth = stroke.GetWidth();
575 LINE_STYLE lineStyle = stroke.GetLineStyle();
576
577 if( lineStyle <= LINE_STYLE::FIRST_TYPE || aRenderSettings == nullptr )
578 TransformOvalToPolygon( aBuffer, ptA, ptB, lineWidth, aMaxError, aErrorLoc );
579 else
580 {
581 SHAPE_SEGMENT seg( ptA, ptB );
582 KIGFX::PCB_RENDER_SETTINGS defaultRenderSettings;
583
584 KIGFX::RENDER_SETTINGS* currSettings = aRenderSettings;
585
586 if( currSettings == nullptr )
587 currSettings = &defaultRenderSettings;
588
589 STROKE_PARAMS::Stroke( &seg, lineStyle, lineWidth, currSettings,
590 [&]( VECTOR2I a, VECTOR2I b )
591 {
592 if( a == b )
593 TransformCircleToPolygon( aBuffer, a, lineWidth / 2, aMaxError, aErrorLoc );
594 else
595 TransformOvalToPolygon( aBuffer, a + 1, b, lineWidth, aMaxError, aErrorLoc );
596 } );
597 }
598 } );
599
600 for( PCB_TABLECELL* cell : m_cells )
601 {
602 cell->TransformTextToPolySet( aBuffer, 0, aMaxError, ERROR_INSIDE );
603 }
604}
605
606
608 int aClearance, int aMaxError, ERROR_LOC aErrorLoc,
609 KIGFX::RENDER_SETTINGS* aRenderSettings ) const
610{
611 if( aClearance <= 0 )
612 TransformGraphicItemsToPolySet( aBuffer, aMaxError, aErrorLoc, aRenderSettings );
613 else
614 {
615 SHAPE_POLY_SET tmp;
616 TransformGraphicItemsToPolySet( tmp, aMaxError, aErrorLoc, aRenderSettings );
617 tmp.Inflate( aClearance, CORNER_STRATEGY::CHAMFER_ALL_CORNERS, aMaxError );
618 aBuffer.Append( tmp );
619 }
620}
621
622
623INSPECT_RESULT PCB_TABLE::Visit( INSPECTOR aInspector, void* aTestData, const std::vector<KICAD_T>& aScanTypes )
624{
625 for( KICAD_T scanType : aScanTypes )
626 {
627 if( scanType == PCB_TABLE_T )
628 {
629 if( INSPECT_RESULT::QUIT == aInspector( this, aTestData ) )
631 }
632
633 if( scanType == PCB_TABLECELL_T )
634 {
635 for( PCB_TABLECELL* cell : m_cells )
636 {
637 if( INSPECT_RESULT::QUIT == aInspector( cell, (void*) this ) )
639 }
640 }
641 }
642
644}
645
646
647wxString PCB_TABLE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
648{
649 return wxString::Format( _( "%d column table" ), m_colCount );
650}
651
652
654{
655 return BITMAPS::table;
656}
657
658
659bool PCB_TABLE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
660{
661 BOX2I rect = GetBoundingBox();
662
663 rect.Inflate( aAccuracy );
664
665 return rect.Contains( aPosition );
666}
667
668
669bool PCB_TABLE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
670{
671 BOX2I rect = aRect;
672
673 rect.Inflate( aAccuracy );
674
675 if( aContained )
676 return rect.Contains( GetBoundingBox() );
677
678 return rect.Intersects( GetBoundingBox() );
679}
680
681
682bool PCB_TABLE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
683{
684 return KIGEOM::ShapeHitTest( aPoly, *GetEffectiveShape(), aContained );
685}
686
687
688void PCB_TABLE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
689{
690 // Don't use GetShownText() here; we want to show the user the variable references
691 aList.emplace_back( _( "Table" ), wxString::Format( _( "%d Columns" ), m_colCount ) );
692}
693
694
695int PCB_TABLE::Compare( const PCB_TABLE* aTable, const PCB_TABLE* aOther )
696{
697 int diff;
698
699 if( ( diff = (int) aTable->GetCells().size() - (int) aOther->GetCells().size() ) != 0 )
700 return diff;
701
702 if( ( diff = aTable->GetColCount() - aOther->GetColCount() ) != 0 )
703 return diff;
704
705 for( int col = 0; col < aTable->GetColCount(); ++col )
706 {
707 if( ( diff = aTable->GetColWidth( col ) - aOther->GetColWidth( col ) ) != 0 )
708 return diff;
709 }
710
711 for( int row = 0; row < aTable->GetRowCount(); ++row )
712 {
713 if( ( diff = aTable->GetRowHeight( row ) - aOther->GetRowHeight( row ) ) != 0 )
714 return diff;
715 }
716
717 for( int row = 0; row < aTable->GetRowCount(); ++row )
718 {
719 for( int col = 0; col < aTable->GetColCount(); ++col )
720 {
721 PCB_TABLECELL* cell = aTable->GetCell( row, col );
722 PCB_TABLECELL* other = aOther->GetCell( row, col );
723
724 if( ( diff = cell->PCB_SHAPE::Compare( other ) ) != 0 )
725 return diff;
726
727 if( ( diff = cell->EDA_TEXT::Compare( other ) ) != 0 )
728 return diff;
729 }
730 }
731
732 return 0;
733}
734
735
736bool PCB_TABLE::operator==( const BOARD_ITEM& aBoardItem ) const
737{
738 if( Type() != aBoardItem.Type() )
739 return false;
740
741 const PCB_TABLE& other = static_cast<const PCB_TABLE&>( aBoardItem );
742
743 return *this == other;
744}
745
746
747bool PCB_TABLE::operator==( const PCB_TABLE& aOther ) const
748{
749 if( m_cells.size() != aOther.m_cells.size() )
750 return false;
751
752 if( m_strokeExternal != aOther.m_strokeExternal )
753 return false;
754
756 return false;
757
758 if( m_borderStroke != aOther.m_borderStroke )
759 return false;
760
761 if( m_strokeRows != aOther.m_strokeRows )
762 return false;
763
764 if( m_strokeColumns != aOther.m_strokeColumns )
765 return false;
766
768 return false;
769
770 if( m_colWidths != aOther.m_colWidths )
771 return false;
772
773 if( m_rowHeights != aOther.m_rowHeights )
774 return false;
775
776 for( int ii = 0; ii < (int) m_cells.size(); ++ii )
777 {
778 if( !( *m_cells[ii] == *aOther.m_cells[ii] ) )
779 return false;
780 }
781
782 return true;
783}
784
785
786double PCB_TABLE::Similarity( const BOARD_ITEM& aOther ) const
787{
788 if( aOther.Type() != Type() )
789 return 0.0;
790
791 const PCB_TABLE& other = static_cast<const PCB_TABLE&>( aOther );
792
793 if( m_cells.size() != other.m_cells.size() )
794 return 0.1;
795
796 double similarity = 1.0;
797
799 similarity *= 0.9;
800
802 similarity *= 0.9;
803
804 if( m_borderStroke != other.m_borderStroke )
805 similarity *= 0.9;
806
807 if( m_strokeRows != other.m_strokeRows )
808 similarity *= 0.9;
809
810 if( m_strokeColumns != other.m_strokeColumns )
811 similarity *= 0.9;
812
814 similarity *= 0.9;
815
816 if( m_colWidths != other.m_colWidths )
817 similarity *= 0.9;
818
819 if( m_rowHeights != other.m_rowHeights )
820 similarity *= 0.9;
821
822 for( int ii = 0; ii < (int) m_cells.size(); ++ii )
823 similarity *= m_cells[ii]->Similarity( *other.m_cells[ii] );
824
825 return similarity;
826}
827
828
829static struct PCB_TABLE_DESC
830{
832 {
834
835 if( lineStyleEnum.Choices().GetCount() == 0 )
836 {
837 lineStyleEnum.Map( LINE_STYLE::SOLID, _HKI( "Solid" ) )
838 .Map( LINE_STYLE::DASH, _HKI( "Dashed" ) )
839 .Map( LINE_STYLE::DOT, _HKI( "Dotted" ) )
840 .Map( LINE_STYLE::DASHDOT, _HKI( "Dash-Dot" ) )
841 .Map( LINE_STYLE::DASHDOTDOT, _HKI( "Dash-Dot-Dot" ) );
842 }
843
846
851
852 propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Start X" ),
855 propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Start Y" ),
858
859 const wxString tableProps = _( "Table Properties" );
860
861 propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "External Border" ),
863 tableProps );
864
865 propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "Header Border" ),
867 tableProps );
868
869 propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Border Width" ),
872 tableProps );
873
874 propMgr.AddProperty( new PROPERTY_ENUM<PCB_TABLE, LINE_STYLE>( _HKI( "Border Style" ),
876 tableProps );
877
878 propMgr.AddProperty( new PROPERTY<PCB_TABLE, COLOR4D>( _HKI( "Border Color" ),
880 tableProps );
881
882 propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "Row Separators" ),
884 tableProps );
885
886 propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "Cell Separators" ),
888 tableProps );
889
890 propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Separators Width" ),
893 tableProps );
894
895 propMgr.AddProperty( new PROPERTY_ENUM<PCB_TABLE, LINE_STYLE>( _HKI( "Separators Style" ),
897 tableProps );
898
899 propMgr.AddProperty( new PROPERTY<PCB_TABLE, COLOR4D>( _HKI( "Separators Color" ),
901 tableProps );
902 }
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
@ ERROR_INSIDE
constexpr int ARC_LOW_DEF
Definition base_units.h:140
BITMAPS
A list of all bitmap identifiers.
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
Abstract interface for BOARD_ITEMs capable of storing other items inside.
BOARD_ITEM_CONTAINER(BOARD_ITEM *aParent, KICAD_T aType)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:86
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:268
PCB_LAYER_ID m_layer
Definition board_item.h:490
bool m_isLocked
Definition board_item.h:492
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
constexpr const Vec & GetPosition() const
Definition box2.h:211
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:558
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:658
constexpr const Vec GetCenter() const
Definition box2.h:230
constexpr coord_type GetLeft() const
Definition box2.h:228
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:168
constexpr coord_type GetRight() const
Definition box2.h:217
constexpr coord_type GetTop() const
Definition box2.h:229
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:311
constexpr coord_type GetBottom() const
Definition box2.h:222
The base class for create windows for drawing purpose.
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:112
virtual void SetParent(EDA_ITEM *aParent)
Definition eda_item.cpp:93
std::vector< VECTOR2I > GetCornersInSequence(EDA_ANGLE angle) const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:232
void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:236
virtual EDA_ANGLE GetDrawRotation() const
Definition eda_text.h:404
virtual void ClearRenderCache()
Definition eda_text.cpp:688
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition property.h:727
static ENUM_MAP< T > & Instance()
Definition property.h:721
wxPGChoices & Choices()
Definition property.h:770
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:105
PCB specific render settings.
Definition pcb_painter.h:82
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
void SetPosition(const VECTOR2I &aPos) override
Definition pcb_shape.h:78
VECTOR2I GetPosition() const override
Definition pcb_shape.h:79
int GetRowSpan() const
int GetColSpan() const
VECTOR2I GetEnd() const
STROKE_PARAMS m_separatorsStroke
Definition pcb_table.h:301
bool StrokeRows() const
Definition pcb_table.h:107
int GetRowCount() const
Definition pcb_table.h:125
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
void TransformGraphicItemsToPolySet(SHAPE_POLY_SET &aBuffer, int aMaxError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings) const
Convert graphic items (segments and texts) to a set of polygonal shapes.
std::vector< PCB_TABLECELL * > m_cells
Definition pcb_table.h:306
void SetColWidth(int aCol, int aWidth)
Definition pcb_table.h:130
int m_colCount
Definition pcb_table.h:303
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
bool m_strokeRows
Definition pcb_table.h:299
void Move(const VECTOR2I &aMoveVector) override
Move this object.
int GetPositionY() const
Definition pcb_table.h:120
bool StrokeHeaderSeparator() const
Definition pcb_table.h:65
bool StrokeColumns() const
Definition pcb_table.h:104
void SetBorderStyle(const LINE_STYLE aStyle)
Definition pcb_table.h:73
void SetStrokeHeaderSeparator(bool aDoStroke)
Definition pcb_table.h:64
void SetSeparatorsColor(const COLOR4D &aColor)
Definition pcb_table.h:100
bool m_strokeExternal
Definition pcb_table.h:296
STROKE_PARAMS m_borderStroke
Definition pcb_table.h:298
bool m_strokeColumns
Definition pcb_table.h:300
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
bool StrokeExternal() const
Definition pcb_table.h:62
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
int GetSeparatorsWidth() const
Definition pcb_table.h:89
void SetPositionX(int x)
Definition pcb_table.h:117
void SetStrokeExternal(bool aDoStroke)
Definition pcb_table.h:61
PCB_TABLECELL * GetCell(int aRow, int aCol) const
Definition pcb_table.h:150
std::vector< PCB_TABLECELL * > GetCells() const
Definition pcb_table.h:160
void Autosize()
int GetBorderWidth() const
Definition pcb_table.h:71
COLOR4D GetBorderColor() const
Definition pcb_table.h:83
void TransformShapeToPolySet(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, KIGFX::RENDER_SETTINGS *aRenderSettings=nullptr) const override
Convert the TABLE shape to a polyset.
bool operator==(const PCB_TABLE &aOther) const
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &aScanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
int GetColCount() const
Definition pcb_table.h:123
void SetStrokeColumns(bool aDoStroke)
Definition pcb_table.h:103
const STROKE_PARAMS & GetSeparatorsStroke() const
Definition pcb_table.h:86
std::map< int, int > m_colWidths
Definition pcb_table.h:304
virtual void swapData(BOARD_ITEM *aImage) override
Definition pcb_table.cpp:78
int GetPositionX() const
Definition pcb_table.h:119
void Normalize() override
Perform any normalization required after a user rotate and/or flip.
void AddCell(PCB_TABLECELL *aCell)
Definition pcb_table.h:165
const STROKE_PARAMS & GetBorderStroke() const
Definition pcb_table.h:68
void SetPositionY(int y)
Definition pcb_table.h:118
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
void SetStrokeRows(bool aDoStroke)
Definition pcb_table.h:106
bool m_StrokeHeaderSeparator
Definition pcb_table.h:297
void RunOnChildren(const std::function< void(BOARD_ITEM *)> &aFunction, RECURSE_MODE aMode) const override
Invoke a function on all children.
double Similarity(const BOARD_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth=false) const override
Convert the item shape to a closed polygon.
void DrawBorders(const std::function< void(const VECTOR2I &aPt1, const VECTOR2I &aPt2, const STROKE_PARAMS &aStroke)> &aCallback) const
LINE_STYLE GetBorderStyle() const
Definition pcb_table.h:74
static int Compare(const PCB_TABLE *aTable, const PCB_TABLE *aOther)
int GetColWidth(int aCol) const
Definition pcb_table.h:132
VECTOR2I GetPosition() const override
void SetSeparatorsWidth(int aWidth)
Definition pcb_table.h:88
COLOR4D GetSeparatorsColor() const
Definition pcb_table.h:101
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
LINE_STYLE GetSeparatorsStyle() const
Definition pcb_table.h:92
void SetBorderColor(const COLOR4D &aColor)
Definition pcb_table.h:82
PCB_TABLE(BOARD_ITEM *aParent, int aLineWidth)
Definition pcb_table.cpp:38
void SetSeparatorsStyle(const LINE_STYLE aStyle)
Definition pcb_table.h:91
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
void SetRowHeight(int aRow, int aHeight)
Definition pcb_table.h:140
void SetPosition(const VECTOR2I &aPos) override
void SetBorderWidth(int aWidth)
Definition pcb_table.h:70
int GetRowHeight(int aRow) const
Definition pcb_table.h:142
std::map< int, int > m_rowHeights
Definition pcb_table.h:305
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
int GetMarginLeft() const
Definition pcb_textbox.h:96
int GetMarginRight() const
Definition pcb_textbox.h:98
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Represent a set of closed polygons.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
Simple container to manage line stroke parameters.
int GetWidth() const
LINE_STYLE GetLineStyle() const
static void Stroke(const SHAPE *aShape, LINE_STYLE aLineStyle, int aWidth, const KIGFX::RENDER_SETTINGS *aRenderSettings, const std::function< void(const VECTOR2I &a, const VECTOR2I &b)> &aStroker)
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
@ CHAMFER_ALL_CORNERS
All angles are chamfered.
static bool empty(const wxTextEntryBase *aCtrl)
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
RECURSE_MODE
Definition eda_item.h:52
@ RECURSE
Definition eda_item.h:53
INSPECT_RESULT
Definition eda_item.h:46
const INSPECTOR_FUNC & INSPECTOR
std::function passed to nested users by ref, avoids copying std::function.
Definition eda_item.h:93
a few functions useful in geometry calculations.
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition layer_id.cpp:173
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
Definition layer_ids.h:782
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition layer_ids.h:184
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
FLIP_DIRECTION
Definition mirror.h:27
@ LEFT_RIGHT
Flip left to right (around the Y axis)
Definition mirror.h:28
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
Definition mirror.h:29
bool ShapeHitTest(const SHAPE_LINE_CHAIN &aHitter, const SHAPE &aHittee, bool aHitteeContained)
Perform a shape-to-shape hit test.
#define _HKI(x)
Definition page_info.cpp:44
static struct PCB_TABLE_DESC _PCB_TABLE_DESC
#define TYPE_HASH(x)
Definition property.h:74
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
Definition property.h:65
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
constexpr double correction
LINE_STYLE
Dashed line types.
std::vector< std::vector< std::string > > table
VECTOR2I end
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:229
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:75
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition typeinfo.h:92
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
Definition typeinfo.h:91
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687