KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_label.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 (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2015 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <base_units.h>
27#include <pgm_base.h>
28#include <sch_edit_frame.h>
29#include <sch_plotter.h>
30#include <widgets/msgpanel.h>
31#include <bitmaps.h>
32#include <string_utils.h>
33#include <schematic.h>
35#include <sch_painter.h>
36#include <default_values.h>
37#include <wx/debug.h>
38#include <wx/log.h>
42#include <core/kicad_algo.h>
43#include <core/mirror.h>
44#include <trigo.h>
45#include <sch_label.h>
46
48
49
50bool IncrementLabelMember( wxString& name, int aIncrement )
51{
52 if( name.IsEmpty() )
53 return true;
54
55 wxString suffix;
56 wxString digits;
57 wxString outputFormat;
58 wxString outputNumber;
59 int ii = name.Len() - 1;
60 int dCount = 0;
61
62 while( ii >= 0 && !wxIsdigit( name.GetChar( ii ) ) )
63 {
64 suffix = name.GetChar( ii ) + suffix;
65 ii--;
66 }
67
68 while( ii >= 0 && wxIsdigit( name.GetChar( ii ) ) )
69 {
70 digits = name.GetChar( ii ) + digits;
71 ii--;
72 dCount++;
73 }
74
75 if( digits.IsEmpty() )
76 return true;
77
78 long number = 0;
79
80 if( digits.ToLong( &number ) )
81 {
82 number += aIncrement;
83
84 // Don't let result go below zero
85
86 if( number > -1 )
87 {
88 name.Remove( ii + 1 );
89 //write out a format string with correct number of leading zeroes
90 outputFormat.Printf( wxS( "%%0%dld" ), dCount );
91 //write out the number using the format string
92 outputNumber.Printf( outputFormat, number );
93 name << outputNumber << suffix;
94 return true;
95 }
96 }
97
98 return false;
99}
100
101
102/* Coding polygons for global symbol graphic shapes.
103 * the first parml is the number of corners
104 * others are the corners coordinates in reduced units
105 * the real coordinate is the reduced coordinate * text half size
106 */
107static int TemplateIN_HN[] = { 6, 0, 0, -1, -1, -2, -1, -2, 1, -1, 1, 0, 0 };
108static int TemplateIN_HI[] = { 6, 0, 0, 1, 1, 2, 1, 2, -1, 1, -1, 0, 0 };
109static int TemplateIN_UP[] = { 6, 0, 0, 1, -1, 1, -2, -1, -2, -1, -1, 0, 0 };
110static int TemplateIN_BOTTOM[] = { 6, 0, 0, 1, 1, 1, 2, -1, 2, -1, 1, 0, 0 };
111
112static int TemplateOUT_HN[] = { 6, -2, 0, -1, 1, 0, 1, 0, -1, -1, -1, -2, 0 };
113static int TemplateOUT_HI[] = { 6, 2, 0, 1, -1, 0, -1, 0, 1, 1, 1, 2, 0 };
114static int TemplateOUT_UP[] = { 6, 0, -2, 1, -1, 1, 0, -1, 0, -1, -1, 0, -2 };
115static int TemplateOUT_BOTTOM[] = { 6, 0, 2, 1, 1, 1, 0, -1, 0, -1, 1, 0, 2 };
116
117static int TemplateUNSPC_HN[] = { 5, 0, -1, -2, -1, -2, 1, 0, 1, 0, -1 };
118static int TemplateUNSPC_HI[] = { 5, 0, -1, 2, -1, 2, 1, 0, 1, 0, -1 };
119static int TemplateUNSPC_UP[] = { 5, 1, 0, 1, -2, -1, -2, -1, 0, 1, 0 };
120static int TemplateUNSPC_BOTTOM[] = { 5, 1, 0, 1, 2, -1, 2, -1, 0, 1, 0 };
121
122static int TemplateBIDI_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
123static int TemplateBIDI_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
124static int TemplateBIDI_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
125static int TemplateBIDI_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
126
127static int Template3STATE_HN[] = { 5, 0, 0, -1, -1, -2, 0, -1, 1, 0, 0 };
128static int Template3STATE_HI[] = { 5, 0, 0, 1, -1, 2, 0, 1, 1, 0, 0 };
129static int Template3STATE_UP[] = { 5, 0, 0, -1, -1, 0, -2, 1, -1, 0, 0 };
130static int Template3STATE_BOTTOM[] = { 5, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0 };
131
132static int* TemplateShape[5][4] =
133{
139};
140
141
143{
144 switch( aType )
145 {
146 case LABEL_FLAG_SHAPE::L_INPUT: return _( "Input" );
147 case LABEL_FLAG_SHAPE::L_OUTPUT: return _( "Output" );
148 case LABEL_FLAG_SHAPE::L_BIDI: return _( "Bidirectional" );
149 case LABEL_FLAG_SHAPE::L_TRISTATE: return _( "Tri-State" );
150 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: return _( "Passive" );
151 default: return wxT( "???" );
152 }
153}
154
155
157{
158 SPIN newSpin = m_spin;
159
160 switch( m_spin )
161 {
162 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::BOTTOM; break;
163 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::RIGHT; break;
164 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::UP; break;
165 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::LEFT; break;
166 }
167
168 return SPIN_STYLE( newSpin );
169}
170
171
173{
174 SPIN newSpin = m_spin;
175
176 switch( m_spin )
177 {
178 case SPIN_STYLE::UP: newSpin = SPIN_STYLE::BOTTOM; break;
179 case SPIN_STYLE::BOTTOM: newSpin = SPIN_STYLE::UP; break;
180 case SPIN_STYLE::LEFT: break;
181 case SPIN_STYLE::RIGHT: break;
182 }
183
184 return SPIN_STYLE( newSpin );
185}
186
187
189{
190 SPIN newSpin = m_spin;
191
192 switch( m_spin )
193 {
194 case SPIN_STYLE::LEFT: newSpin = SPIN_STYLE::RIGHT; break;
195 case SPIN_STYLE::RIGHT: newSpin = SPIN_STYLE::LEFT; break;
196 case SPIN_STYLE::UP: break;
197 case SPIN_STYLE::BOTTOM: break;
198 }
199
200 return SPIN_STYLE( newSpin );
201}
202
203
204SCH_LABEL_BASE::SCH_LABEL_BASE( const VECTOR2I& aPos, const wxString& aText, KICAD_T aType ) :
205 SCH_TEXT( aPos, aText, aType ),
206 m_shape( L_UNSPECIFIED ),
207 m_connectionType( CONNECTION_TYPE::NONE ),
208 m_isDangling( true ),
209 m_lastResolvedColor( COLOR4D::UNSPECIFIED )
210{
211 SetMultilineAllowed( false );
212 ClearFieldsAutoplaced(); // fields are not yet autoplaced.
213
214 if( !HasTextVars() )
216}
217
218
220 SCH_TEXT( aLabel ),
221 m_shape( aLabel.m_shape ),
222 m_connectionType( aLabel.m_connectionType ),
223 m_isDangling( aLabel.m_isDangling ),
224 m_lastResolvedColor( aLabel.m_lastResolvedColor ),
225 m_cached_driver_name( aLabel.m_cached_driver_name )
226{
227 SetMultilineAllowed( false );
228
229 m_fields = aLabel.m_fields;
230
231 for( SCH_FIELD& field : m_fields )
232 field.SetParent( this );
233}
234
235
237{
238 SCH_TEXT::operator=( aLabel );
239
241
242 return *this;
243}
244
245
246const wxString SCH_LABEL_BASE::GetDefaultFieldName( const wxString& aName, bool aUseDefaultName )
247{
248 if( aName == wxT( "Intersheetrefs" ) )
249 return _( "Sheet References" );
250 else if( aName == wxT( "Netclass" ) )
251 return _( "Net Class" );
252 else if( aName.IsEmpty() && aUseDefaultName )
253 return _( "Field" );
254 else
255 return aName;
256}
257
258
259bool SCH_LABEL_BASE::IsType( const std::vector<KICAD_T>& aScanTypes ) const
260{
261 if( SCH_TEXT::IsType( aScanTypes ) )
262 return true;
263
264 for( KICAD_T scanType : aScanTypes )
265 {
266 if( scanType == SCH_LABEL_LOCATE_ANY_T )
267 return true;
268 }
269
270 wxCHECK_MSG( Schematic(), false, wxT( "No parent SCHEMATIC set for SCH_LABEL!" ) );
271
272 // Ensure m_connected_items for Schematic()->CurrentSheet() exists.
273 // Can be not the case when "this" is living in clipboard
274 if( m_connected_items.find( Schematic()->CurrentSheet() ) == m_connected_items.end() )
275 return false;
276
277 const SCH_ITEM_SET& item_set = m_connected_items.at( Schematic()->CurrentSheet() );
278
279 for( KICAD_T scanType : aScanTypes )
280 {
281 if( scanType == SCH_LABEL_LOCATE_WIRE_T )
282 {
283 for( SCH_ITEM* connection : item_set )
284 {
285 if( connection->IsType( { SCH_ITEM_LOCATE_WIRE_T, SCH_PIN_T } ) )
286 return true;
287 }
288 }
289
290 if ( scanType == SCH_LABEL_LOCATE_BUS_T )
291 {
292 for( SCH_ITEM* connection : item_set )
293 {
294 if( connection->IsType( { SCH_ITEM_LOCATE_BUS_T } ) )
295 return true;
296 }
297 }
298 }
299
300 return false;
301}
302
303
305{
306 SCH_TEXT::SwapData( aItem );
307
308 SCH_LABEL_BASE* label = static_cast<SCH_LABEL_BASE*>( aItem );
309
310 m_fields.swap( label->m_fields );
311 std::swap( m_fieldsAutoplaced, label->m_fieldsAutoplaced );
312
313 for( SCH_FIELD& field : m_fields )
314 field.SetParent( this );
315
316 for( SCH_FIELD& field : label->m_fields )
317 field.SetParent( label );
318
319 std::swap( m_shape, label->m_shape );
320 std::swap( m_connectionType, label->m_connectionType );
321 std::swap( m_isDangling, label->m_isDangling );
322 std::swap( m_lastResolvedColor, label->m_lastResolvedColor );
323}
324
325
327{
328 if( GetTextColor() != COLOR4D::UNSPECIFIED )
330 else if( !IsConnectivityDirty() )
331 m_lastResolvedColor = GetEffectiveNetClass()->GetSchematicColor();
332
333 return m_lastResolvedColor;
334}
335
336
338{
339 // Assume "Right" and Left" mean which side of the anchor the text will be on
340 // Thus we want to left justify text up against the anchor if we are on the right
341 switch( aSpinStyle )
342 {
343 default:
344 wxFAIL_MSG( "Bad spin style" );
346
347 case SPIN_STYLE::RIGHT: // Horiz Normal Orientation
350 break;
351
352 case SPIN_STYLE::UP: // Vert Orientation UP
355 break;
356
357 case SPIN_STYLE::LEFT: // Horiz Orientation - Right justified
360 break;
361
362 case SPIN_STYLE::BOTTOM: // Vert Orientation BOTTOM
365 break;
366 }
367
369}
370
371
373{
375 {
377 return SPIN_STYLE::BOTTOM;
378 else
379 return SPIN_STYLE::UP;
380 }
381 else
382 {
384 return SPIN_STYLE::LEFT;
385 else
386 return SPIN_STYLE::RIGHT;
387 }
388}
389
390
392{
393 VECTOR2I text_offset;
394
395 // add an offset to x (or y) position to aid readability of text on a wire or line
396 int dist = GetTextOffset( aSettings ) + GetPenWidth();
397
398 switch( GetSpinStyle() )
399 {
400 case SPIN_STYLE::UP:
401 case SPIN_STYLE::BOTTOM: text_offset.x = -dist; break; // Vert Orientation
402 default:
403 case SPIN_STYLE::LEFT:
404 case SPIN_STYLE::RIGHT: text_offset.y = -dist; break; // Horiz Orientation
405 }
406
407 return text_offset;
408}
409
410void SCH_LABEL_BASE::SetPosition( const VECTOR2I& aPosition )
411{
412 VECTOR2I offset = aPosition - GetTextPos();
413 Move( offset );
414}
415
416
417void SCH_LABEL_BASE::Move( const VECTOR2I& aMoveVector )
418{
419 SCH_TEXT::Move( aMoveVector );
420
421 for( SCH_FIELD& field : m_fields )
422 field.Offset( aMoveVector );
423}
424
425
426void SCH_LABEL_BASE::Rotate( const VECTOR2I& aCenter )
427{
428 VECTOR2I pt = GetTextPos();
429 RotatePoint( pt, aCenter, ANGLE_90 );
430 VECTOR2I offset = pt - GetTextPos();
431
432 Rotate90( false );
433
434 SetTextPos( GetTextPos() + offset );
435
436 for( SCH_FIELD& field : m_fields )
437 field.SetTextPos( field.GetTextPos() + offset );
438}
439
440
441void SCH_LABEL_BASE::Rotate90( bool aClockwise )
442{
443 SCH_TEXT::Rotate90( aClockwise );
444
446 {
447 AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
448 }
449 else
450 {
451 for( SCH_FIELD& field : m_fields )
452 {
453 if( field.GetTextAngle().IsVertical()
454 && field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
455 {
456 if( !aClockwise )
457 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
458
459 field.SetTextAngle( ANGLE_HORIZONTAL );
460 }
461 else if( field.GetTextAngle().IsVertical()
462 && field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
463 {
464 if( !aClockwise )
465 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
466
467 field.SetTextAngle( ANGLE_HORIZONTAL );
468 }
469 else if( field.GetTextAngle().IsHorizontal()
470 && field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
471 {
472 if( aClockwise )
473 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
474
475 field.SetTextAngle( ANGLE_VERTICAL );
476 }
477 else if( field.GetTextAngle().IsHorizontal()
478 && field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
479 {
480 if( aClockwise )
481 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
482
483 field.SetTextAngle( ANGLE_VERTICAL );
484 }
485
486 VECTOR2I pos = field.GetTextPos();
487 RotatePoint( pos, GetPosition(), aClockwise ? -ANGLE_90 : ANGLE_90 );
488 field.SetTextPos( pos );
489 }
490 }
491}
492
493
494void SCH_LABEL_BASE::MirrorSpinStyle( bool aLeftRight )
495{
496 SCH_TEXT::MirrorSpinStyle( aLeftRight );
497
498 for( SCH_FIELD& field : m_fields )
499 {
500 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
501 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
502 {
503 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
504 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
505 else
506 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
507 }
508
509 VECTOR2I pos = field.GetTextPos();
511
512 if( aLeftRight )
513 pos.x = GetPosition().x + delta.x;
514 else
515 pos.y = GetPosition().y + delta.y;
516
517 field.SetTextPos( pos );
518 }
519}
520
521
523{
524 VECTOR2I old_pos = GetPosition();
526
527 for( SCH_FIELD& field : m_fields )
528 {
529 if( field.GetTextAngle() == ANGLE_HORIZONTAL )
530 field.FlipHJustify();
531
532 VECTOR2I pos = field.GetTextPos();
533 VECTOR2I delta = old_pos - pos;
534 pos.x = GetPosition().x + delta.x;
535
536 field.SetPosition( pos );
537 }
538}
539
540
542{
543 VECTOR2I old_pos = GetPosition();
545
546 for( SCH_FIELD& field : m_fields )
547 {
548 if( field.GetTextAngle() == ANGLE_VERTICAL )
549 field.FlipHJustify();
550
551 VECTOR2I pos = field.GetTextPos();
552 VECTOR2I delta = old_pos - pos;
553 pos.y = GetPosition().y + delta.y;
554
555 field.SetPosition( pos );
556 }
557}
558
559
560bool SCH_LABEL_BASE::IncrementLabel( int aIncrement )
561{
562 wxString text = GetText();
563
564 if( IncrementLabelMember( text, aIncrement ) )
565 {
566 SetText( text );
567 return true;
568 }
569
570 return false;
571}
572
573
574bool SCH_LABEL_BASE::operator==( const SCH_ITEM& aOther ) const
575{
576 const SCH_LABEL_BASE* other = dynamic_cast<const SCH_LABEL_BASE*>( &aOther );
577
578 if( !other )
579 return false;
580
581 if( m_shape != other->m_shape )
582 return false;
583
584 if( m_connectionType != other->m_connectionType )
585 return false;
586
587 if( m_fields.size() != other->m_fields.size() )
588 return false;
589
590 for( size_t ii = 0; ii < m_fields.size(); ++ii )
591 {
592 if( !( m_fields[ii] == other->m_fields[ii] ) )
593 return false;
594 }
595
596 return SCH_TEXT::operator==( aOther );
597}
598
599
600double SCH_LABEL_BASE::Similarity( const SCH_ITEM& aOther ) const
601{
602 const SCH_LABEL_BASE* other = dynamic_cast<const SCH_LABEL_BASE*>( &aOther );
603
604 if( !other )
605 return 0.0;
606
607 if( m_Uuid == other->m_Uuid )
608 return 1.0;
609
610 double similarity = SCH_TEXT::Similarity( aOther );
611
612 if( typeid( *this ) != typeid( aOther ) )
613 similarity *= 0.9;
614
615 if( m_shape == other->m_shape )
616 similarity *= 0.9;
617
618 if( m_connectionType == other->m_connectionType )
619 similarity *= 0.9;
620
621 for( size_t ii = 0; ii < m_fields.size(); ++ii )
622 {
623 if( ii >= other->m_fields.size() )
624 break;
625
626 similarity *= m_fields[ii].Similarity( other->m_fields[ii] );
627 }
628
629 int diff = std::abs( int( m_fields.size() ) - int( other->m_fields.size() ) );
630
631 similarity *= std::pow( 0.9, diff );
632
633 return similarity;
634}
635
636
637void SCH_LABEL_BASE::AutoplaceFields( SCH_SCREEN* aScreen, bool aManual )
638{
639 int margin = GetTextOffset() * 2;
640 int labelLen = GetBodyBoundingBox().GetSizeMax();
641 int accumulated = GetTextHeight() / 2;
642
643 if( Type() == SCH_GLOBAL_LABEL_T )
644 accumulated += margin + GetPenWidth() + margin;
645
646 for( SCH_FIELD& field : m_fields )
647 {
648 VECTOR2I offset( 0, 0 );
649
650 switch( GetSpinStyle() )
651 {
652 default:
653 case SPIN_STYLE::LEFT:
654 field.SetTextAngle( ANGLE_HORIZONTAL );
655 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
656
657 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
658 offset.x = - ( labelLen + margin );
659 else
660 offset.y = accumulated + field.GetTextHeight() / 2;
661
662 break;
663
664 case SPIN_STYLE::UP:
665 field.SetTextAngle( ANGLE_VERTICAL );
666 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
667
668 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
669 offset.y = - ( labelLen + margin );
670 else
671 offset.x = accumulated + field.GetTextHeight() / 2;
672
673 break;
674
676 field.SetTextAngle( ANGLE_HORIZONTAL );
677 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
678
679 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
680 offset.x = labelLen + margin;
681 else
682 offset.y = accumulated + field.GetTextHeight() / 2;
683
684 break;
685
687 field.SetTextAngle( ANGLE_VERTICAL );
688 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
689
690 if( field.GetCanonicalName() == wxT( "Intersheetrefs" ) )
691 offset.y = labelLen + margin;
692 else
693 offset.x = accumulated + field.GetTextHeight() / 2;
694
695 break;
696 }
697
698 field.SetTextPos( GetTextPos() + offset );
699
700 if( field.GetCanonicalName() != wxT( "Intersheetrefs" ) )
701 accumulated += field.GetTextHeight() + margin;
702 }
703
705}
706
707
708void SCH_LABEL_BASE::GetIntersheetRefs( std::vector<std::pair<wxString, wxString>>* pages )
709{
710 wxCHECK( pages, /* void */ );
711
712 if( Schematic() )
713 {
714 auto it = Schematic()->GetPageRefsMap().find( GetText() );
715
716 if( it != Schematic()->GetPageRefsMap().end() )
717 {
718 std::vector<int> pageListCopy;
719
720 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
721
722 if( !Schematic()->Settings().m_IntersheetRefsListOwnPage )
723 {
724 int currentPage = Schematic()->CurrentSheet().GetVirtualPageNumber();
725 alg::delete_matching( pageListCopy, currentPage );
726
727 if( pageListCopy.empty() )
728 return;
729 }
730
731 std::sort( pageListCopy.begin(), pageListCopy.end() );
732
733 std::map<int, wxString> sheetPages = Schematic()->GetVirtualPageToSheetPagesMap();
734 std::map<int, wxString> sheetNames = Schematic()->GetVirtualPageToSheetNamesMap();
735
736 for( int pageNum : pageListCopy )
737 pages->push_back( { sheetPages[ pageNum ], sheetNames[ pageNum ] } );
738 }
739 }
740}
741
742
743void SCH_LABEL_BASE::GetContextualTextVars( wxArrayString* aVars ) const
744{
745 for( const SCH_FIELD& field : m_fields )
746 aVars->push_back( field.GetCanonicalName().Upper() );
747
748 aVars->push_back( wxT( "OP" ) );
749 aVars->push_back( wxT( "CONNECTION_TYPE" ) );
750 aVars->push_back( wxT( "SHORT_NET_NAME" ) );
751 aVars->push_back( wxT( "NET_NAME" ) );
752 aVars->push_back( wxT( "NET_CLASS" ) );
753}
754
755
756bool SCH_LABEL_BASE::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token,
757 int aDepth ) const
758{
759 static wxRegEx operatingPoint( wxT( "^"
760 "OP"
761 "(.([0-9])?([a-zA-Z]*))?"
762 "$" ) );
763
764 wxCHECK( aPath, false );
765
766 SCHEMATIC* schematic = Schematic();
767
768 if( !schematic )
769 return false;
770
771 if( operatingPoint.Matches( *token ) )
772 {
773 int precision = 3;
774 wxString precisionStr( operatingPoint.GetMatch( *token, 2 ) );
775 wxString range( operatingPoint.GetMatch( *token, 3 ) );
776
777 if( !precisionStr.IsEmpty() )
778 precision = precisionStr[0] - '0';
779
780 if( range.IsEmpty() )
781 range = wxS( "~V" );
782
783 const SCH_CONNECTION* connection = Connection();
784 *token = wxS( "?" );
785
786 if( connection )
787 *token = schematic->GetOperatingPoint( connection->Name( false ), precision, range );
788
789 return true;
790 }
791
792 if( token->Contains( ':' ) )
793 {
794 if( schematic->ResolveCrossReference( token, aDepth + 1 ) )
795 return true;
796 }
797
799 && token->IsSameAs( wxT( "CONNECTION_TYPE" ) ) )
800 {
801 const SCH_LABEL_BASE* label = static_cast<const SCH_LABEL_BASE*>( this );
802 *token = getElectricalTypeLabel( label->GetShape() );
803 return true;
804 }
805 else if( token->IsSameAs( wxT( "SHORT_NET_NAME" ) ) )
806 {
807 const SCH_CONNECTION* connection = Connection();
808 *token = wxEmptyString;
809
810 if( connection )
811 *token = connection->LocalName();
812
813 return true;
814 }
815 else if( token->IsSameAs( wxT( "NET_NAME" ) ) )
816 {
817 const SCH_CONNECTION* connection = Connection();
818 *token = wxEmptyString;
819
820 if( connection )
821 *token = connection->Name();
822
823 return true;
824 }
825 else if( token->IsSameAs( wxT( "NET_CLASS" ) ) )
826 {
827 const SCH_CONNECTION* connection = Connection();
828 *token = wxEmptyString;
829
830 if( connection )
831 *token = GetEffectiveNetClass()->GetName();
832
833 return true;
834 }
835
836 for( const SCH_FIELD& field : m_fields)
837 {
838 if( token->IsSameAs( field.GetName() ) )
839 {
840 *token = field.GetShownText( false, aDepth + 1 );
841 return true;
842 }
843 }
844
845 // See if parent can resolve it (these will recurse to ancestors)
846
847 if( Type() == SCH_SHEET_PIN_T && m_parent )
848 {
849 SCH_SHEET* sheet = static_cast<SCH_SHEET*>( m_parent );
850
851 SCH_SHEET_PATH path = *aPath;
852 path.push_back( sheet );
853
854 if( sheet->ResolveTextVar( &path, token, aDepth + 1 ) )
855 return true;
856 }
857 else
858 {
859 if( aPath->Last()->ResolveTextVar( aPath, token, aDepth + 1 ) )
860 return true;
861 }
862
863 return false;
864}
865
866
868{
869 return !HasTextVars();
870}
871
872
874{
876}
877
878
880{
882
883 if( !HasTextVars() )
885}
886
887
888wxString SCH_LABEL_BASE::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowExtraText,
889 int aDepth ) const
890{
891 std::function<bool( wxString* )> textResolver =
892 [&]( wxString* token ) -> bool
893 {
894 return ResolveTextVar( aPath, token, aDepth );
895 };
896
897 wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
898
899 if( text == wxS( "~" ) ) // Legacy placeholder for empty string
900 {
901 text = wxS( "" );
902 }
903 else if( HasTextVars() )
904 {
905 if( aDepth < 10 )
906 text = ExpandTextVars( text, &textResolver );
907 }
908
909 return text;
910}
911
912
913void SCH_LABEL_BASE::RunOnChildren( const std::function<void( SCH_ITEM* )>& aFunction )
914{
915 for( SCH_FIELD& field : m_fields )
916 aFunction( &field );
917}
918
919
920bool SCH_LABEL_BASE::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
921{
922 return SCH_ITEM::Matches( UnescapeString( GetText() ), aSearchData );
923}
924
925
926bool SCH_LABEL_BASE::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
927{
928 EDA_SEARCH_DATA localSearchData( aSearchData );
929 localSearchData.findString = EscapeString( aSearchData.findString, CTX_NETNAME );
930 localSearchData.replaceString = EscapeString( aSearchData.replaceString, CTX_NETNAME );
931
932 return EDA_TEXT::Replace( localSearchData );
933}
934
935
937 const std::vector<KICAD_T>& aScanTypes )
938{
939 if( IsType( aScanTypes ) )
940 {
941 if( INSPECT_RESULT::QUIT == aInspector( this, nullptr ) )
942 return INSPECT_RESULT::QUIT;
943 }
944
945 for( KICAD_T scanType : aScanTypes )
946 {
947 if( scanType == SCH_LOCATE_ANY_T || scanType == SCH_FIELD_T )
948 {
949 for( SCH_FIELD& field : m_fields )
950 {
951 if( INSPECT_RESULT::QUIT == aInspector( &field, this ) )
952 return INSPECT_RESULT::QUIT;
953 }
954 }
955 }
956
957 return INSPECT_RESULT::CONTINUE;
958}
959
960
961void SCH_LABEL_BASE::GetEndPoints( std::vector<DANGLING_END_ITEM>& aItemList )
962{
963 DANGLING_END_ITEM item( LABEL_END, this, GetTextPos() );
964 aItemList.push_back( item );
965}
966
967
968std::vector<VECTOR2I> SCH_LABEL_BASE::GetConnectionPoints() const
969{
970 return { GetTextPos() };
971}
972
973
974void SCH_LABEL_BASE::ViewGetLayers( int aLayers[], int& aCount ) const
975{
976 aCount = 5;
977 aLayers[0] = LAYER_DANGLING;
978 aLayers[1] = LAYER_DEVICE;
979 aLayers[2] = LAYER_NETCLASS_REFS;
980 aLayers[3] = LAYER_FIELDS;
981 aLayers[4] = LAYER_SELECTION_SHADOWS;
982}
983
984
986{
987 double ratio;
988
989 if( aSettings )
990 ratio = static_cast<const SCH_RENDER_SETTINGS*>( aSettings )->m_LabelSizeRatio;
991 else if( Schematic() )
993 else
994 ratio = DEFAULT_LABEL_SIZE_RATIO; // For previews (such as in Preferences), etc.
995
996 return KiROUND( ratio * GetTextSize().y );
997}
998
999
1001{
1002 // build the bounding box of the label only, without taking into account its fields
1003
1004 BOX2I box;
1005 std::vector<VECTOR2I> pts;
1006
1007 CreateGraphicShape( nullptr, pts, GetTextPos() );
1008
1009 for( const VECTOR2I& pt : pts )
1010 box.Merge( pt );
1011
1012 box.Inflate( GetEffectiveTextPenWidth() / 2 );
1013 box.Normalize();
1014 return box;
1015}
1016
1017
1019{
1020 // build the bounding box of the entire label, including its fields
1021
1022 BOX2I box = GetBodyBoundingBox();
1023
1024 for( const SCH_FIELD& field : m_fields )
1025 {
1026 if( field.IsVisible() )
1027 {
1028 BOX2I fieldBBox = field.GetBoundingBox();
1029
1030 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1031 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1032
1033 box.Merge( fieldBBox );
1034 }
1035 }
1036
1037 box.Normalize();
1038
1039 return box;
1040}
1041
1042
1043bool SCH_LABEL_BASE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
1044{
1045 BOX2I bbox = GetBodyBoundingBox();
1046 bbox.Inflate( aAccuracy );
1047
1048 if( bbox.Contains( aPosition ) )
1049 return true;
1050
1051 for( const SCH_FIELD& field : m_fields )
1052 {
1053 if( field.IsVisible() )
1054 {
1055 BOX2I fieldBBox = field.GetBoundingBox();
1056 fieldBBox.Inflate( aAccuracy );
1057
1058 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1059 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1060
1061 if( fieldBBox.Contains( aPosition ) )
1062 return true;
1063 }
1064 }
1065
1066 return false;
1067}
1068
1069
1070bool SCH_LABEL_BASE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
1071{
1072 BOX2I rect = aRect;
1073
1074 rect.Inflate( aAccuracy );
1075
1076 if( aContained )
1077 {
1078 return rect.Contains( GetBoundingBox() );
1079 }
1080 else
1081 {
1082 if( rect.Intersects( GetBodyBoundingBox() ) )
1083 return true;
1084
1085 for( const SCH_FIELD& field : m_fields )
1086 {
1087 if( field.IsVisible() )
1088 {
1089 BOX2I fieldBBox = field.GetBoundingBox();
1090
1091 if( Type() == SCH_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
1092 fieldBBox.Offset( GetSchematicTextOffset( nullptr ) );
1093
1094 if( rect.Intersects( fieldBBox ) )
1095 return true;
1096 }
1097 }
1098
1099 return false;
1100 }
1101}
1102
1103
1104bool SCH_LABEL_BASE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
1105 std::vector<DANGLING_END_ITEM>& aItemListByPos,
1106 const SCH_SHEET_PATH* aPath )
1107{
1108 bool previousState = m_isDangling;
1109 VECTOR2I text_pos = GetTextPos();
1110 m_isDangling = true;
1111 m_connectionType = CONNECTION_TYPE::NONE;
1112
1113 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, text_pos );
1114 it < aItemListByPos.end() && it->GetPosition() == text_pos; it++ )
1115 {
1116 DANGLING_END_ITEM& item = *it;
1117
1118 if( item.GetItem() == this )
1119 continue;
1120
1121 switch( item.GetType() )
1122 {
1123 case PIN_END:
1124 case LABEL_END:
1125 case SHEET_LABEL_END:
1126 case NO_CONNECT_END:
1127 if( text_pos == item.GetPosition() )
1128 {
1129 m_isDangling = false;
1130
1131 if( aPath && item.GetType() != PIN_END )
1132 AddConnectionTo( *aPath, static_cast<SCH_ITEM*>( item.GetItem() ) );
1133 }
1134 break;
1135
1136 default: break;
1137 }
1138
1139 if( !m_isDangling )
1140 break;
1141 }
1142
1143 if( m_isDangling )
1144 {
1145 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, BUS_END );
1146 it < aItemListByType.end() && it->GetType() == BUS_END; it++ )
1147 {
1148 DANGLING_END_ITEM& item = *it;
1149 DANGLING_END_ITEM& nextItem = *( ++it );
1150
1151 int accuracy = 1; // We have rounding issues with an accuracy of 0
1152
1153 m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(), nextItem.GetPosition(),
1154 accuracy );
1155
1156 if( m_isDangling )
1157 continue;
1158
1159 m_connectionType = CONNECTION_TYPE::BUS;
1160
1161 // Add the line to the connected items, since it won't be picked
1162 // up by a search of intersecting connection points
1163 if( aPath )
1164 {
1165 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1166 AddConnectionTo( *aPath, sch_item );
1167 sch_item->AddConnectionTo( *aPath, this );
1168 }
1169 break;
1170 }
1171
1172 if( m_isDangling )
1173 {
1174 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_type( aItemListByType, WIRE_END );
1175 it < aItemListByType.end() && it->GetType() == WIRE_END; it++ )
1176 {
1177 DANGLING_END_ITEM& item = *it;
1178 DANGLING_END_ITEM& nextItem = *( ++it );
1179
1180 int accuracy = 1; // We have rounding issues with an accuracy of 0
1181
1182 m_isDangling = !TestSegmentHit( text_pos, item.GetPosition(),
1183 nextItem.GetPosition(), accuracy );
1184
1185 if( m_isDangling )
1186 continue;
1187
1188 m_connectionType = CONNECTION_TYPE::NET;
1189
1190 // Add the line to the connected items, since it won't be picked
1191 // up by a search of intersecting connection points
1192 if( aPath )
1193 {
1194 auto sch_item = static_cast<SCH_ITEM*>( item.GetItem() );
1195 AddConnectionTo( *aPath, sch_item );
1196 sch_item->AddConnectionTo( *aPath, this );
1197 }
1198 break;
1199 }
1200 }
1201 }
1202
1203 if( m_isDangling )
1204 m_connectionType = CONNECTION_TYPE::NONE;
1205
1206 return previousState != m_isDangling;
1207}
1208
1209
1210void SCH_LABEL_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1211{
1212 wxString msg;
1213
1214 switch( Type() )
1215 {
1216 case SCH_LABEL_T: msg = _( "Label" ); break;
1217 case SCH_DIRECTIVE_LABEL_T: msg = _( "Directive Label" ); break;
1218 case SCH_GLOBAL_LABEL_T: msg = _( "Global Label" ); break;
1219 case SCH_HIER_LABEL_T: msg = _( "Hierarchical Label" ); break;
1220 case SCH_SHEET_PIN_T: msg = _( "Hierarchical Sheet Pin" ); break;
1221 default: return;
1222 }
1223
1224 // Don't use GetShownText() here; we want to show the user the variable references
1225 aList.emplace_back( msg, UnescapeString( GetText() ) );
1226
1227 // Display electrical type if it is relevant
1229 aList.emplace_back( _( "Type" ), getElectricalTypeLabel( GetShape() ) );
1230
1231 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
1232
1233 wxString textStyle[] = { _( "Normal" ), _( "Italic" ), _( "Bold" ), _( "Bold Italic" ) };
1234 int style = IsBold() && IsItalic() ? 3 : IsBold() ? 2 : IsItalic() ? 1 : 0;
1235 aList.emplace_back( _( "Style" ), textStyle[style] );
1236
1237 aList.emplace_back( _( "Text Size" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
1238
1239 switch( GetSpinStyle() )
1240 {
1241 case SPIN_STYLE::LEFT: msg = _( "Align right" ); break;
1242 case SPIN_STYLE::UP: msg = _( "Align bottom" ); break;
1243 case SPIN_STYLE::RIGHT: msg = _( "Align left" ); break;
1244 case SPIN_STYLE::BOTTOM: msg = _( "Align top" ); break;
1245 default: msg = wxT( "???" ); break;
1246 }
1247
1248 aList.emplace_back( _( "Justification" ), msg );
1249
1250 SCH_CONNECTION* conn = nullptr;
1251
1252 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
1253 conn = Connection();
1254
1255 if( conn )
1256 {
1257 conn->AppendInfoToMsgPanel( aList );
1258
1259 if( !conn->IsBus() )
1260 {
1261 aList.emplace_back( _( "Resolved Netclass" ),
1262 UnescapeString( GetEffectiveNetClass()->GetName() ) );
1263 }
1264 }
1265}
1266
1267
1268void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground,
1269 const SCH_PLOT_SETTINGS& aPlotSettings ) const
1270{
1271 static std::vector<VECTOR2I> s_poly;
1272
1273 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
1274 SCH_CONNECTION* connection = Connection();
1275 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1276 COLOR4D color = settings->GetLayerColor( layer );
1277 int penWidth = GetEffectiveTextPenWidth( settings->GetDefaultPenWidth() );
1278
1279 if( aPlotter->GetColorMode() && GetTextColor() != COLOR4D::UNSPECIFIED )
1280 color = GetTextColor();
1281
1282 penWidth = std::max( penWidth, settings->GetMinPenWidth() );
1283 aPlotter->SetCurrentLineWidth( penWidth );
1284
1285 KIFONT::FONT* font = GetFont();
1286
1287 if( !font )
1288 font = KIFONT::FONT::GetFont( settings->GetDefaultFont(), IsBold(), IsItalic() );
1289
1290 VECTOR2I textpos = GetTextPos() + GetSchematicTextOffset( aPlotter->RenderSettings() );
1291 CreateGraphicShape( aPlotter->RenderSettings(), s_poly, GetTextPos() );
1292
1294 attrs.m_StrokeWidth = penWidth;
1295 attrs.m_Multiline = false;
1296
1297 if( aBackground )
1298 {
1299 // No filled shapes (yet)
1300 }
1301 else
1302 {
1303 aPlotter->PlotText( textpos, color, GetShownText( true ), attrs, font, GetFontMetrics() );
1304
1305 if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
1306 {
1307 aPlotter->MoveTo( s_poly[0] );
1308 aPlotter->LineTo( s_poly[1] );
1309 aPlotter->PenFinish();
1310
1311 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1312 aPlotter->FilledCircle( s_poly[2], diameter , FILLED, nullptr );
1313 }
1314 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1315 {
1316 aPlotter->MoveTo( s_poly[0] );
1317 aPlotter->LineTo( s_poly[1] );
1318 aPlotter->PenFinish();
1319
1320 int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
1321 aPlotter->ThickCircle( s_poly[2], diameter, penWidth, FILLED, nullptr );
1322 }
1323 else
1324 {
1325 if( !s_poly.empty() )
1326 aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth );
1327 }
1328
1329 // Plot attributes to a hypertext menu
1330 if( aPlotSettings.m_PDFPropertyPopups )
1331 {
1332 std::vector<wxString> properties;
1333
1334 if( connection )
1335 {
1336 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Net" ),
1337 connection->Name() ) );
1338
1339 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), _( "Resolved netclass" ),
1340 GetEffectiveNetClass()->GetName() ) );
1341 }
1342
1343 for( const SCH_FIELD& field : GetFields() )
1344 {
1345 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ), field.GetName(),
1346 field.GetShownText( false ) ) );
1347 }
1348
1349 if( !properties.empty() )
1350 aPlotter->HyperlinkMenu( GetBodyBoundingBox(), properties );
1351 }
1352
1353 if( Type() == SCH_HIER_LABEL_T )
1354 {
1355 aPlotter->Bookmark( GetBodyBoundingBox(), GetShownText( false ),
1356 _( "Hierarchical Labels" ) );
1357 }
1358 }
1359
1360 for( const SCH_FIELD& field : m_fields )
1361 field.Plot( aPlotter, aBackground, aPlotSettings );
1362}
1363
1364
1365void SCH_LABEL_BASE::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset )
1366{
1367 static std::vector<VECTOR2I> s_poly;
1368
1369 SCH_CONNECTION* connection = Connection();
1370 int layer = ( connection && connection->IsBus() ) ? LAYER_BUS : m_layer;
1371 wxDC* DC = aSettings->GetPrintDC();
1372 COLOR4D color = aSettings->GetLayerColor( layer );
1373 bool blackAndWhiteMode = GetGRForceBlackPenState();
1374 int penWidth = std::max( GetPenWidth(), aSettings->GetDefaultPenWidth() );
1375 VECTOR2I text_offset = aOffset + GetSchematicTextOffset( aSettings );
1376
1377 if( !blackAndWhiteMode && GetTextColor() != COLOR4D::UNSPECIFIED )
1378 color = GetTextColor();
1379
1380 EDA_TEXT::Print( aSettings, text_offset, color );
1381
1382 CreateGraphicShape( aSettings, s_poly, GetTextPos() + aOffset );
1383
1384 if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
1385 {
1386 GRLine( DC, s_poly[0], s_poly[1], penWidth, color );
1387
1388 int radius = ( s_poly[2] - s_poly[1] ).EuclideanNorm();
1389 GRFilledCircle( DC, s_poly[2], radius, penWidth, color, color );
1390 }
1391 else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
1392 {
1393 GRLine( DC, s_poly[0], s_poly[1], penWidth, color );
1394
1395 int radius = ( s_poly[2] - s_poly[1] ).EuclideanNorm();
1396 GRCircle( DC, s_poly[2], radius, penWidth, color );
1397 }
1398 else
1399 {
1400 if( !s_poly.empty() )
1401 GRPoly( DC, s_poly.size(), &s_poly[0], false, penWidth, color, color );
1402 }
1403
1404 for( SCH_FIELD& field : m_fields )
1405 field.Print( aSettings, aOffset );
1406}
1407
1409{
1411}
1412
1414{
1415 m_autoRotateOnPlacement = autoRotate;
1416}
1417
1418SCH_LABEL::SCH_LABEL( const VECTOR2I& pos, const wxString& text ) :
1420{
1422 m_shape = LABEL_FLAG_SHAPE::L_INPUT;
1423 m_isDangling = true;
1424}
1425
1426
1428{
1429 BOX2I rect = GetTextBox();
1430
1431 rect.Offset( 0, -GetTextOffset() );
1433
1434 if( !GetTextAngle().IsZero() )
1435 {
1436 // Rotate rect
1437 VECTOR2I pos = rect.GetOrigin();
1438 VECTOR2I end = rect.GetEnd();
1439
1440 RotatePoint( pos, GetTextPos(), GetTextAngle() );
1441 RotatePoint( end, GetTextPos(), GetTextAngle() );
1442
1443 rect.SetOrigin( pos );
1444 rect.SetEnd( end );
1445
1446 rect.Normalize();
1447 }
1448
1449 // Labels have a position point that is outside of the TextBox
1450 rect.Merge( GetPosition() );
1451
1452 return rect;
1453}
1454
1455
1456wxString SCH_LABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
1457{
1458 return wxString::Format( _( "Label '%s'" ),
1460}
1461
1462
1464{
1465 return BITMAPS::add_line_label;
1466}
1467
1468
1470 SCH_LABEL_BASE( pos, wxEmptyString, SCH_DIRECTIVE_LABEL_T )
1471{
1473 m_shape = LABEL_FLAG_SHAPE::F_ROUND;
1476 m_isDangling = true;
1477}
1478
1479
1481{
1482 SCH_LABEL_BASE::SwapData( aItem );
1483
1484 SCH_DIRECTIVE_LABEL* label = static_cast<SCH_DIRECTIVE_LABEL*>( aItem );
1485
1486 std::swap( m_pinLength, label->m_pinLength );
1487 std::swap( m_symbolSize, label->m_symbolSize );
1488}
1489
1490
1492 SCH_LABEL_BASE( aClassLabel )
1493{
1494 m_pinLength = aClassLabel.m_pinLength;
1495 m_symbolSize = aClassLabel.m_symbolSize;
1496}
1497
1498
1500{
1501 int pen = 0;
1502
1503 if( Schematic() )
1505
1506 return GetEffectiveTextPenWidth( pen );
1507}
1508
1509
1511{
1512 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1513 // vertical shape (like a text reduced to only "I" letter).
1514 // So the mirroring is not exactly similar to a SCH_TEXT item
1515 SCH_TEXT::MirrorSpinStyle( !aLeftRight );
1516
1517 for( SCH_FIELD& field : m_fields )
1518 {
1519 if( ( aLeftRight && field.GetTextAngle().IsHorizontal() )
1520 || ( !aLeftRight && field.GetTextAngle().IsVertical() ) )
1521 {
1522 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1523 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1524 else
1525 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1526 }
1527
1528 VECTOR2I pos = field.GetTextPos();
1530
1531 if( aLeftRight )
1532 pos.x = GetPosition().x + delta.x;
1533 else
1534 pos.y = GetPosition().y + delta.y;
1535
1536 field.SetTextPos( pos );
1537 }
1538}
1539
1540
1542{
1543 VECTOR2I old_pos = GetPosition();
1544 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1545 // vertical shape (like a text reduced to only "I" letter).
1546 // So the mirroring is not exactly similar to a SCH_TEXT item
1547 // Text is NOT really mirrored; it is moved to a suitable horizontal position
1548 SetSpinStyle( GetSpinStyle().MirrorX() );
1549
1550 SetTextX( MIRRORVAL( GetTextPos().x, aCenter ) );
1551
1552 for( SCH_FIELD& field : m_fields )
1553 {
1554 if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT )
1555 field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
1556 else if( field.GetHorizJustify() == GR_TEXT_H_ALIGN_RIGHT )
1557 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1558
1559 VECTOR2I pos = field.GetTextPos();
1560 VECTOR2I delta = old_pos - pos;
1561 pos.x = GetPosition().x + delta.x;
1562
1563 field.SetPosition( pos );
1564 }
1565}
1566
1567
1569{
1570 VECTOR2I old_pos = GetPosition();
1571 // The "text" is in fact a graphic shape. For a horizontal "text", it looks like a
1572 // vertical shape (like a text reduced to only "I" letter).
1573 // So the mirroring is not exactly similar to a SCH_TEXT item
1574 // Text is NOT really mirrored; it is moved to a suitable vertical position
1575 SetSpinStyle( GetSpinStyle().MirrorY() );
1576
1577 SetTextY( MIRRORVAL( GetTextPos().y, aCenter ) );
1578
1579 for( SCH_FIELD& field : m_fields )
1580 {
1581 VECTOR2I pos = field.GetTextPos();
1582 VECTOR2I delta = old_pos - pos;
1583 pos.y = GetPosition().y + delta.y;
1584
1585 field.SetPosition( pos );
1586 }
1587}
1588
1589
1591 std::vector<VECTOR2I>& aPoints,
1592 const VECTOR2I& aPos ) const
1593{
1594 int symbolSize = m_symbolSize;
1595
1596 aPoints.clear();
1597
1598 switch( m_shape )
1599 {
1600 case LABEL_FLAG_SHAPE::F_DOT:
1601 symbolSize = KiROUND( symbolSize * 0.7 );
1603
1604 case LABEL_FLAG_SHAPE::F_ROUND:
1605 // First 3 points are used for generating shape
1606 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1607 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1608 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1609 // These points are just used to bulk out the bounding box
1610 aPoints.emplace_back( VECTOR2I( -m_symbolSize, m_pinLength ) );
1611 aPoints.emplace_back( VECTOR2I( 0, m_pinLength ) );
1612 aPoints.emplace_back( VECTOR2I( m_symbolSize, m_pinLength + symbolSize ) );
1613 break;
1614
1615 case LABEL_FLAG_SHAPE::F_DIAMOND:
1616 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1617 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1618 aPoints.emplace_back( VECTOR2I( -2 * m_symbolSize, m_pinLength ) );
1619 aPoints.emplace_back( VECTOR2I( 0, m_pinLength + symbolSize ) );
1620 aPoints.emplace_back( VECTOR2I( 2 * m_symbolSize, m_pinLength ) );
1621 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1622 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1623 break;
1624
1625 case LABEL_FLAG_SHAPE::F_RECTANGLE:
1626 symbolSize = KiROUND( symbolSize * 0.8 );
1627
1628 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1629 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1630 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength - symbolSize ) );
1631 aPoints.emplace_back( VECTOR2I( -2 * symbolSize, m_pinLength + symbolSize ) );
1632 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength + symbolSize ) );
1633 aPoints.emplace_back( VECTOR2I( 2 * symbolSize, m_pinLength - symbolSize ) );
1634 aPoints.emplace_back( VECTOR2I( 0, m_pinLength - symbolSize ) );
1635 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1636 break;
1637
1638 default:
1639 break;
1640 }
1641
1642 // Rotate outlines and move corners to real position
1643 for( VECTOR2I& aPoint : aPoints )
1644 {
1645 switch( GetSpinStyle() )
1646 {
1647 default:
1648 case SPIN_STYLE::LEFT: break;
1649 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
1650 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
1651 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
1652 }
1653
1654 aPoint += aPos;
1655 }
1656}
1657
1658
1660{
1661 int margin = GetTextOffset();
1662 int symbolWidth = m_symbolSize;
1663 int origin = m_pinLength;
1664
1665 if( m_shape == LABEL_FLAG_SHAPE::F_DIAMOND || m_shape == LABEL_FLAG_SHAPE::F_RECTANGLE )
1666 symbolWidth *= 2;
1667
1668 if( IsItalic() )
1669 margin = KiROUND( margin * 1.5 );
1670
1671 VECTOR2I offset;
1672
1673 for( SCH_FIELD& field : m_fields )
1674 {
1675 switch( GetSpinStyle() )
1676 {
1677 default:
1678 case SPIN_STYLE::LEFT:
1679 field.SetTextAngle( ANGLE_HORIZONTAL );
1680 offset = { symbolWidth + margin, origin };
1681 break;
1682
1683 case SPIN_STYLE::UP:
1684 field.SetTextAngle( ANGLE_VERTICAL );
1685 offset = { -origin, -( symbolWidth + margin ) };
1686 break;
1687
1688 case SPIN_STYLE::RIGHT:
1689 field.SetTextAngle( ANGLE_HORIZONTAL );
1690 offset = { symbolWidth + margin, -origin };
1691 break;
1692
1693 case SPIN_STYLE::BOTTOM:
1694 field.SetTextAngle( ANGLE_VERTICAL );
1695 offset = { origin, -( symbolWidth + margin ) };
1696 break;
1697 }
1698
1699 field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
1700 field.SetTextPos( GetPosition() + offset );
1701
1702 origin -= field.GetTextHeight() + margin;
1703 }
1704
1706}
1707
1708
1710{
1711 if( m_fields.empty() )
1712 {
1713 return _( "Directive Label" );
1714 }
1715 else
1716 {
1717 return wxString::Format( _( "Directive Label [%s %s]" ),
1718 UnescapeString( m_fields[0].GetName() ),
1720 }
1721}
1722
1723
1724SCH_GLOBALLABEL::SCH_GLOBALLABEL( const VECTOR2I& pos, const wxString& text ) :
1726{
1728 m_shape = LABEL_FLAG_SHAPE::L_BIDI;
1729 m_isDangling = true;
1730
1732
1733 m_fields.emplace_back( SCH_FIELD( pos, 0, this, wxT( "Sheet References" ) ) );
1734 m_fields[0].SetText( wxT( "${INTERSHEET_REFS}" ) );
1735 m_fields[0].SetVisible( false );
1736 m_fields[0].SetLayer( LAYER_INTERSHEET_REFS );
1737 m_fields[0].SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
1738}
1739
1740
1742 SCH_LABEL_BASE( aGlobalLabel )
1743{
1744}
1745
1746
1748{
1749 int horiz = GetLabelBoxExpansion( aSettings );
1750
1751 // Center the text on the center line of "E" instead of "R" to make room for an overbar
1752 int vert = GetTextHeight() * 0.0715;
1753
1754 switch( m_shape )
1755 {
1756 case LABEL_FLAG_SHAPE::L_INPUT:
1757 case LABEL_FLAG_SHAPE::L_BIDI:
1758 case LABEL_FLAG_SHAPE::L_TRISTATE:
1759 horiz += GetTextHeight() * 3 / 4; // Use three-quarters-height as proxy for triangle size
1760 break;
1761
1762 case LABEL_FLAG_SHAPE::L_OUTPUT:
1763 case LABEL_FLAG_SHAPE::L_UNSPECIFIED:
1764 default:
1765 break;
1766 }
1767
1768 switch( GetSpinStyle() )
1769 {
1770 default:
1771 case SPIN_STYLE::LEFT: return VECTOR2I( -horiz, vert );
1772 case SPIN_STYLE::UP: return VECTOR2I( vert, -horiz );
1773 case SPIN_STYLE::RIGHT: return VECTOR2I( horiz, vert );
1774 case SPIN_STYLE::BOTTOM: return VECTOR2I( vert, horiz );
1775 }
1776}
1777
1778
1780{
1781 SCH_LABEL_BASE::SetSpinStyle( aSpinStyle );
1783}
1784
1785
1786bool SCH_GLOBALLABEL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token,
1787 int aDepth ) const
1788{
1789 wxCHECK( aPath, false );
1790
1791 SCHEMATIC* schematic = Schematic();
1792
1793 if( !schematic )
1794 return false;
1795
1796 if( token->IsSameAs( wxT( "INTERSHEET_REFS" ) ) )
1797 {
1798 SCHEMATIC_SETTINGS& settings = schematic->Settings();
1799 wxString ref;
1800 auto it = schematic->GetPageRefsMap().find( GetText() );
1801
1802 if( it == schematic->GetPageRefsMap().end() )
1803 {
1804 ref = "?";
1805 }
1806 else
1807 {
1808 std::vector<int> pageListCopy;
1809
1810 pageListCopy.insert( pageListCopy.end(), it->second.begin(), it->second.end() );
1811 std::sort( pageListCopy.begin(), pageListCopy.end() );
1812
1813 if( !settings.m_IntersheetRefsListOwnPage )
1814 {
1815 int currentPage = schematic->CurrentSheet().GetVirtualPageNumber();
1816 alg::delete_matching( pageListCopy, currentPage );
1817 }
1818
1819 std::map<int, wxString> sheetPages = schematic->GetVirtualPageToSheetPagesMap();
1820
1821 if( ( settings.m_IntersheetRefsFormatShort ) && ( pageListCopy.size() > 2 ) )
1822 {
1823 ref.Append( wxString::Format( wxT( "%s..%s" ),
1824 sheetPages[pageListCopy.front()],
1825 sheetPages[pageListCopy.back()] ) );
1826 }
1827 else
1828 {
1829 for( const int& pageNo : pageListCopy )
1830 ref.Append( wxString::Format( wxT( "%s," ), sheetPages[pageNo] ) );
1831
1832 if( !ref.IsEmpty() && ref.Last() == ',' )
1833 ref.RemoveLast();
1834 }
1835 }
1836
1837 *token = settings.m_IntersheetRefsPrefix + ref + settings.m_IntersheetRefsSuffix;
1838 return true;
1839 }
1840
1841 return SCH_LABEL_BASE::ResolveTextVar( aPath, token, aDepth );
1842}
1843
1844
1845void SCH_GLOBALLABEL::ViewGetLayers( int aLayers[], int& aCount ) const
1846{
1847 aCount = 6;
1848 aLayers[0] = LAYER_DANGLING;
1849 aLayers[1] = LAYER_DEVICE;
1850 aLayers[2] = LAYER_INTERSHEET_REFS;
1851 aLayers[3] = LAYER_NETCLASS_REFS;
1852 aLayers[4] = LAYER_FIELDS;
1853 aLayers[5] = LAYER_SELECTION_SHADOWS;
1854}
1855
1856
1858 std::vector<VECTOR2I>& aPoints,
1859 const VECTOR2I& aPos ) const
1860{
1861 int margin = GetLabelBoxExpansion( aRenderSettings );
1862 int halfSize = ( GetTextHeight() / 2 ) + margin;
1863 int linewidth = GetPenWidth();
1864 int symb_len = GetTextBox().GetWidth() + 2 * margin;
1865
1866 int x = symb_len + linewidth + 3;
1867 int y = halfSize + linewidth + 3;
1868
1869 aPoints.clear();
1870
1871 // Create outline shape : 6 points
1872 aPoints.emplace_back( VECTOR2I( 0, 0 ) );
1873 aPoints.emplace_back( VECTOR2I( 0, -y ) ); // Up
1874 aPoints.emplace_back( VECTOR2I( -x, -y ) ); // left
1875 aPoints.emplace_back( VECTOR2I( -x, 0 ) ); // Up left
1876 aPoints.emplace_back( VECTOR2I( -x, y ) ); // left down
1877 aPoints.emplace_back( VECTOR2I( 0, y ) ); // down
1878
1879 int x_offset = 0;
1880
1881 switch( m_shape )
1882 {
1883 case LABEL_FLAG_SHAPE::L_INPUT:
1884 x_offset = -halfSize;
1885 aPoints[0].x += halfSize;
1886 break;
1887
1888 case LABEL_FLAG_SHAPE::L_OUTPUT:
1889 aPoints[3].x -= halfSize;
1890 break;
1891
1892 case LABEL_FLAG_SHAPE::L_BIDI:
1893 case LABEL_FLAG_SHAPE::L_TRISTATE:
1894 x_offset = -halfSize;
1895 aPoints[0].x += halfSize;
1896 aPoints[3].x -= halfSize;
1897 break;
1898
1899 case LABEL_FLAG_SHAPE::L_UNSPECIFIED:
1900 default:
1901 break;
1902 }
1903
1904 // Rotate outlines and move corners in real position
1905 for( VECTOR2I& aPoint : aPoints )
1906 {
1907 aPoint.x += x_offset;
1908
1909 switch( GetSpinStyle() )
1910 {
1911 default:
1912 case SPIN_STYLE::LEFT: break;
1913 case SPIN_STYLE::UP: RotatePoint( aPoint, -ANGLE_90 ); break;
1914 case SPIN_STYLE::RIGHT: RotatePoint( aPoint, ANGLE_180 ); break;
1915 case SPIN_STYLE::BOTTOM: RotatePoint( aPoint, ANGLE_90 ); break;
1916 }
1917
1918 aPoint += aPos;
1919 }
1920
1921 aPoints.push_back( aPoints[0] ); // closing
1922}
1923
1924
1926{
1927 return wxString::Format( _( "Global Label '%s'" ),
1929}
1930
1931
1933{
1934 return BITMAPS::add_glabel;
1935}
1936
1937
1938SCH_HIERLABEL::SCH_HIERLABEL( const VECTOR2I& pos, const wxString& text, KICAD_T aType ) :
1939 SCH_LABEL_BASE( pos, text, aType )
1940{
1942 m_shape = LABEL_FLAG_SHAPE::L_INPUT;
1943 m_isDangling = true;
1944}
1945
1946
1948{
1949 SCH_LABEL_BASE::SetSpinStyle( aSpinStyle );
1951}
1952
1953
1955 std::vector<VECTOR2I>& aPoints, const VECTOR2I& aPos ) const
1956{
1957 CreateGraphicShape( aSettings, aPoints, aPos, m_shape );
1958}
1959
1960
1962 std::vector<VECTOR2I>& aPoints, const VECTOR2I& aPos,
1963 LABEL_FLAG_SHAPE aShape ) const
1964{
1965 int* Template = TemplateShape[static_cast<int>( aShape )][static_cast<int>( GetSpinStyle() )];
1966 int halfSize = GetTextHeight() / 2;
1967 int imax = *Template;
1968 Template++;
1969
1970 aPoints.clear();
1971
1972 for( int ii = 0; ii < imax; ii++ )
1973 {
1974 VECTOR2I corner;
1975 corner.x = ( halfSize * (*Template) ) + aPos.x;
1976 Template++;
1977
1978 corner.y = ( halfSize * (*Template) ) + aPos.y;
1979 Template++;
1980
1981 aPoints.push_back( corner );
1982 }
1983}
1984
1985
1987{
1988 int penWidth = GetEffectiveTextPenWidth();
1989 int margin = GetTextOffset();
1990
1991 int x = GetTextPos().x;
1992 int y = GetTextPos().y;
1993
1994 int height = GetTextHeight() + penWidth + margin;
1995 int length = GetTextBox().GetWidth();
1996
1997 length += height; // add height for triangular shapes
1998
1999 int dx, dy;
2000
2001 switch( GetSpinStyle() )
2002 {
2003 default:
2004 case SPIN_STYLE::LEFT:
2005 dx = -length;
2006 dy = height;
2008 y -= height / 2;
2009 break;
2010
2011 case SPIN_STYLE::UP:
2012 dx = height;
2013 dy = -length;
2014 x -= height / 2;
2016 break;
2017
2018 case SPIN_STYLE::RIGHT:
2019 dx = length;
2020 dy = height;
2022 y -= height / 2;
2023 break;
2024
2025 case SPIN_STYLE::BOTTOM:
2026 dx = height;
2027 dy = length;
2028 x -= height / 2;
2030 break;
2031 }
2032
2033 BOX2I box( VECTOR2I( x, y ), VECTOR2I( dx, dy ) );
2034 box.Normalize();
2035 return box;
2036}
2037
2038
2040{
2041 VECTOR2I text_offset;
2042 int dist = GetTextOffset( aSettings );
2043
2044 dist += GetTextWidth();
2045
2046 switch( GetSpinStyle() )
2047 {
2048 default:
2049 case SPIN_STYLE::LEFT: text_offset.x = -dist; break; // Orientation horiz normale
2050 case SPIN_STYLE::UP: text_offset.y = -dist; break; // Orientation vert UP
2051 case SPIN_STYLE::RIGHT: text_offset.x = dist; break; // Orientation horiz inverse
2052 case SPIN_STYLE::BOTTOM: text_offset.y = dist; break; // Orientation vert BOTTOM
2053 }
2054
2055 return text_offset;
2056}
2057
2058
2059wxString SCH_HIERLABEL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
2060{
2061 return wxString::Format( _( "Hierarchical Label '%s'" ),
2063}
2064
2065
2067{
2068 return BITMAPS::add_hierarchical_label;
2069}
2070
2071
2073{
2074 wxString msg =
2075#include "sch_text_help_md.h"
2076 ;
2077
2078 HTML_MESSAGE_BOX* dlg = new HTML_MESSAGE_BOX( nullptr, _( "Syntax Help" ) );
2079 wxSize sz( 320, 320 );
2080
2081 dlg->SetMinSize( dlg->ConvertDialogToPixels( sz ) );
2082 dlg->SetDialogSizeInDU( sz.x, sz.y );
2083
2084 wxString html_txt;
2085 ConvertMarkdown2Html( wxGetTranslation( msg ), html_txt );
2086 dlg->AddHTML_Text( html_txt );
2087 dlg->ShowModeless();
2088
2089 return dlg;
2090}
2091
2092
2093static struct SCH_LABEL_DESC
2094{
2096 {
2097 auto& labelShapeEnum = ENUM_MAP<LABEL_SHAPE>::Instance();
2098
2099 if( labelShapeEnum.Choices().GetCount() == 0 )
2100 {
2101 labelShapeEnum.Map( LABEL_SHAPE::LABEL_INPUT, _HKI( "Input" ) )
2102 .Map( LABEL_SHAPE::LABEL_OUTPUT, _HKI( "Output" ) )
2103 .Map( LABEL_SHAPE::LABEL_BIDI, _HKI( "Bidirectional" ) )
2104 .Map( LABEL_SHAPE::LABEL_TRISTATE, _HKI( "Tri-state" ) )
2105 .Map( LABEL_SHAPE::LABEL_PASSIVE, _HKI( "Passive" ) );
2106 }
2107
2112
2116
2120
2124
2129
2130 auto hasLabelShape =
2131 []( INSPECTABLE* aItem ) -> bool
2132 {
2133 if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aItem ) )
2134 return label->IsType( { SCH_GLOBAL_LABEL_T, SCH_HIER_LABEL_T } );
2135
2136 return false;
2137 };
2138
2139 propMgr.AddProperty( new PROPERTY_ENUM<SCH_LABEL_BASE, LABEL_SHAPE>( _HKI( "Shape" ),
2141 .SetAvailableFunc( hasLabelShape );
2142
2143 propMgr.Mask( TYPE_HASH( SCH_LABEL_BASE ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
2144 }
2146
2147
2149{
2151 {
2152 auto& flagShapeEnum = ENUM_MAP<FLAG_SHAPE>::Instance();
2153
2154 if( flagShapeEnum.Choices().GetCount() == 0 )
2155 {
2156 flagShapeEnum.Map( FLAG_SHAPE::FLAG_DOT, _HKI( "Dot" ) )
2157 .Map( FLAG_SHAPE::FLAG_CIRCLE, _HKI( "Circle" ) )
2158 .Map( FLAG_SHAPE::FLAG_DIAMOND, _HKI( "Diamond" ) )
2159 .Map( FLAG_SHAPE::FLAG_RECTANGLE, _HKI( "Rectangle" ) );
2160 }
2161
2167
2169
2172
2173 propMgr.AddProperty( new PROPERTY<SCH_DIRECTIVE_LABEL, int>( _HKI( "Pin length" ),
2175 PROPERTY_DISPLAY::PT_SIZE ) );
2176
2177 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Text" ) );
2178 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
2179 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Italic" ) );
2180 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Bold" ) );
2181 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Horizontal Justification" ) );
2182 propMgr.Mask( TYPE_HASH( SCH_DIRECTIVE_LABEL ), TYPE_HASH( EDA_TEXT ), _HKI( "Vertical Justification" ) );
2183 }
2185
2186
int color
Definition: DXF_plotter.cpp:58
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
void SetOrigin(const Vec &pos)
Definition: box2.h:203
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:120
int GetSizeMax() const
Definition: box2.h:201
const Vec & GetOrigin() const
Definition: box2.h:184
void Offset(coord_type dx, coord_type dy)
Definition: box2.h:225
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:270
coord_type GetWidth() const
Definition: box2.h:188
const Vec GetEnd() const
Definition: box2.h:186
bool Contains(const Vec &aPoint) const
Definition: box2.h:142
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:507
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:256
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:589
static std::vector< DANGLING_END_ITEM >::iterator get_lower_type(std::vector< DANGLING_END_ITEM > &aItemListByType, const DANGLING_END_T &aType)
Definition: sch_item.cpp:423
static std::vector< DANGLING_END_ITEM >::iterator get_lower_pos(std::vector< DANGLING_END_ITEM > &aItemListByPos, const VECTOR2I &aPos)
Definition: sch_item.cpp:412
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition: sch_item.h:86
DANGLING_END_T GetType() const
Definition: sch_item.h:130
EDA_ITEM * GetItem() const
Definition: sch_item.h:128
VECTOR2I GetPosition() const
Definition: sch_item.h:127
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition: eda_item.h:482
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:372
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:100
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:485
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:80
int GetTextHeight() const
Definition: eda_text.h:224
BOX2I GetTextBox(int aLine=-1, bool aInvertY=false) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition: eda_text.cpp:551
const VECTOR2I & GetTextPos() const
Definition: eda_text.h:230
COLOR4D GetTextColor() const
Definition: eda_text.h:227
bool IsItalic() const
Definition: eda_text.h:141
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:131
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:95
void SetTextPos(const VECTOR2I &aPoint)
Definition: eda_text.cpp:403
void SetTextX(int aX)
Definition: eda_text.cpp:409
KIFONT::FONT * GetFont() const
Definition: eda_text.h:207
void SetTextY(int aY)
Definition: eda_text.cpp:415
int GetTextWidth() const
Definition: eda_text.h:221
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:260
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:160
bool Replace(const EDA_SEARCH_DATA &aSearchData)
Helper function used in search and replace dialog.
Definition: eda_text.cpp:329
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition: eda_text.h:114
virtual void cacheShownText()
Definition: eda_text.cpp:448
const TEXT_ATTRIBUTES & GetAttributes() const
Definition: eda_text.h:191
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition: eda_text.cpp:308
bool IsBold() const
Definition: eda_text.h:144
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:106
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:205
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, const COLOR4D &aColor, OUTLINE_MODE aDisplay_mode=FILLED)
Print this text object to the device context aDC.
Definition: eda_text.cpp:715
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.cpp:244
VECTOR2I GetTextSize() const
Definition: eda_text.h:218
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:252
static ENUM_MAP< T > & Instance()
Definition: property.h:653
void SetDialogSizeInDU(int aWidth, int aHeight)
Set the dialog size, using a "logical" value.
void AddHTML_Text(const wxString &message)
Add HTML text (without any change) to message list.
void ShowModeless()
Show a modeless version of the dialog (without an OK button).
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:36
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:146
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
int GetDefaultPenWidth() const
const wxString & GetDefaultFont() const
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxDC * GetPrintDC() const
Store schematic specific render settings.
Definition: sch_painter.h:72
Base plotter engine class.
Definition: plotter.h:104
virtual void ThickCircle(const VECTOR2I &pos, int diametre, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:646
virtual void FilledCircle(const VECTOR2I &pos, int diametre, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:662
void MoveTo(const VECTOR2I &pos)
Definition: plotter.h:242
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:135
virtual void Bookmark(const BOX2I &aBox, const wxString &aName, const wxString &aGroupName=wxEmptyString)
Create a bookmark to a symbol.
Definition: plotter.h:474
bool GetColorMode() const
Definition: plotter.h:132
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
void LineTo(const VECTOR2I &pos)
Definition: plotter.h:247
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr)=0
Draw a polygon ( filled or not ).
void PenFinish()
Definition: plotter.h:258
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:463
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont, const KIFONT::METRICS &aFontMetrics, void *aData=nullptr)
Definition: plotter.cpp:753
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
These settings were stored in SCH_BASE_FRAME previously.
Holds all the data relating to one schematic.
Definition: schematic.h:75
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:136
wxString GetOperatingPoint(const wxString &aNetName, int aPrecision, const wxString &aRange)
Definition: schematic.cpp:718
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:287
std::map< wxString, std::set< int > > & GetPageRefsMap()
Definition: schematic.h:177
std::map< int, wxString > GetVirtualPageToSheetPagesMap() const
Definition: schematic.cpp:462
std::map< int, wxString > GetVirtualPageToSheetNamesMap() const
Definition: schematic.cpp:446
bool ResolveCrossReference(wxString *token, int aDepth) const
Resolves text vars that refer to other items.
Definition: schematic.cpp:411
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString LocalName() const
wxString Name(bool aIgnoreSheet=false) const
bool IsBus() const
void AppendInfoToMsgPanel(std::vector< MSG_PANEL_ITEM > &aList) const
Adds information about the connection object to aList.
void MirrorSpinStyle(bool aLeftRight) override
Definition: sch_label.cpp:1510
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_label.cpp:1480
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_label.cpp:1568
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_label.cpp:1541
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:1659
SCH_DIRECTIVE_LABEL(const VECTOR2I &aPos=VECTOR2I(0, 0))
Definition: sch_label.cpp:1469
void CreateGraphicShape(const RENDER_SETTINGS *aSettings, std::vector< VECTOR2I > &aPoints, const VECTOR2I &aPos) const override
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_label.cpp:1590
FLAG_SHAPE GetFlagShape() const
Definition: sch_label.h:442
int GetPenWidth() const override
Definition: sch_label.cpp:1499
void SetPinLength(int aLength)
Definition: sch_label.h:446
void SetFlagShape(FLAG_SHAPE aShape)
Definition: sch_label.h:443
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:1709
int GetPinLength() const
Definition: sch_label.h:445
Schematic editor (Eeschema) main window.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:52
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_label.cpp:1845
void CreateGraphicShape(const RENDER_SETTINGS *aRenderSettings, std::vector< VECTOR2I > &aPoints, const VECTOR2I &aPos) const override
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_label.cpp:1857
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth) const override
Resolve any references to system tokens supported by the label.
Definition: sch_label.cpp:1786
VECTOR2I GetSchematicTextOffset(const RENDER_SETTINGS *aSettings) const override
This offset depends on the orientation, the type of text, and the area required to draw the associate...
Definition: sch_label.cpp:1747
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
Definition: sch_label.cpp:1779
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:1925
SCH_GLOBALLABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString)
Definition: sch_label.cpp:1724
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:1932
const BOX2I GetBodyBoundingBox() const override
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:1986
void SetSpinStyle(SPIN_STYLE aSpinStyle) override
Definition: sch_label.cpp:1947
void CreateGraphicShape(const RENDER_SETTINGS *aSettings, std::vector< VECTOR2I > &aPoints, const VECTOR2I &aPos) const override
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_label.cpp:1954
SCH_HIERLABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString, KICAD_T aType=SCH_HIER_LABEL_T)
Definition: sch_label.cpp:1938
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:2066
VECTOR2I GetSchematicTextOffset(const RENDER_SETTINGS *aSettings) const override
This offset depends on the orientation, the type of text, and the area required to draw the associate...
Definition: sch_label.cpp:2039
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:2059
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:165
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition: sch_item.cpp:71
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:113
void AddConnectionTo(const SCH_SHEET_PATH &aPath, SCH_ITEM *aItem)
Add a connection link between this item and another.
Definition: sch_item.cpp:203
std::map< SCH_SHEET_PATH, SCH_ITEM_SET, SHEET_PATH_CMP > m_connected_items
Store pointers to other items that are connected to this one, per sheet.
Definition: sch_item.h:545
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition: sch_item.cpp:176
void ClearFieldsAutoplaced()
Definition: sch_item.h:473
FIELDS_AUTOPLACED m_fieldsAutoplaced
Definition: sch_item.h:540
bool IsConnectivityDirty() const
Definition: sch_item.h:453
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:147
const KIFONT::METRICS & GetFontMetrics() const
Definition: sch_item.cpp:331
SCH_LAYER_ID m_layer
Definition: sch_item.h:538
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_item.h:180
bool operator==(const SCH_ITEM &aItem) const override
Definition: sch_label.cpp:574
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_SETTINGS &aPlotSettings) const override
Plot the schematic item to aPlotter.
Definition: sch_label.cpp:1268
const wxString & GetCachedDriverName() const override
Definition: sch_label.cpp:873
SCH_LABEL_BASE(const VECTOR2I &aPos, const wxString &aText, KICAD_T aType)
Definition: sch_label.cpp:204
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_label.cpp:974
COLOR4D m_lastResolvedColor
Definition: sch_label.h:361
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
Definition: sch_label.cpp:888
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_label.cpp:417
bool m_isDangling
Definition: sch_label.h:358
INSPECT_RESULT Visit(INSPECTOR inspector, void *testData, const std::vector< KICAD_T > &scanTypes) override
May be re-implemented for each derived class in order to handle all the types given by its member dat...
Definition: sch_label.cpp:936
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_label.cpp:920
bool HasCachedDriverName() const override
Definition: sch_label.cpp:867
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_label.cpp:1043
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
Definition: sch_label.cpp:961
bool AutoRotateOnPlacement() const
autoRotateOnPlacement
Definition: sch_label.cpp:1408
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_label.cpp:426
SCH_LABEL_BASE & operator=(const SCH_LABEL_BASE &aLabel)
Definition: sch_label.cpp:236
std::vector< SCH_FIELD > m_fields
Definition: sch_label.h:353
CONNECTION_TYPE m_connectionType
Definition: sch_label.h:357
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_label.cpp:522
void SetLabelShape(LABEL_SHAPE aShape)
Definition: sch_label.h:172
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_label.cpp:304
SPIN_STYLE GetSpinStyle() const
Definition: sch_label.cpp:372
void GetIntersheetRefs(std::vector< std::pair< wxString, wxString > > *pages)
Builds an array of { pageNumber, pageName } pairs.
Definition: sch_label.cpp:708
void MirrorSpinStyle(bool aLeftRight) override
Definition: sch_label.cpp:494
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Definition: sch_label.cpp:968
COLOR4D GetLabelColor() const
Definition: sch_label.cpp:326
LABEL_FLAG_SHAPE GetShape() const
Definition: sch_label.h:167
const BOX2I GetBoundingBox() const override
Return the bounding box of the label including its fields.
Definition: sch_label.cpp:1018
bool IsType(const std::vector< KICAD_T > &aScanTypes) const override
Check whether the item is one of the listed types.
Definition: sch_label.cpp:259
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_label.cpp:541
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_label.cpp:410
virtual bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth) const
Resolve any references to system tokens supported by the label.
Definition: sch_label.cpp:756
LABEL_SHAPE GetLabelShape() const
Definition: sch_label.h:171
bool m_autoRotateOnPlacement
Definition: sch_label.h:359
wxString m_cached_driver_name
Definition: sch_label.h:363
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &offset) override
Print a schematic item.
Definition: sch_label.cpp:1365
int GetLabelBoxExpansion(const RENDER_SETTINGS *aSettings=nullptr) const
Definition: sch_label.cpp:985
bool IncrementLabel(int aIncrement)
Increment the label text, if it ends with a number.
Definition: sch_label.cpp:560
void SetAutoRotateOnPlacement(bool autoRotate=true)
setAutoRotateOnPlacement
Definition: sch_label.cpp:1413
void cacheShownText() override
Definition: sch_label.cpp:879
void Rotate90(bool aClockwise) override
Definition: sch_label.cpp:441
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.
Definition: sch_label.cpp:1210
static const wxString GetDefaultFieldName(const wxString &aName, bool aUseDefaultName)
Definition: sch_label.cpp:246
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:637
void RunOnChildren(const std::function< void(SCH_ITEM *)> &aFunction) override
Definition: sch_label.cpp:913
LABEL_FLAG_SHAPE m_shape
Definition: sch_label.h:355
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this label.
Definition: sch_label.cpp:743
virtual const BOX2I GetBodyBoundingBox() const
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:1000
virtual void CreateGraphicShape(const RENDER_SETTINGS *aSettings, std::vector< VECTOR2I > &aPoints, const VECTOR2I &Pos) const
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_label.h:284
std::vector< SCH_FIELD > & GetFields()
Definition: sch_label.h:191
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos, const SCH_SHEET_PATH *aPath=nullptr) override
Test the schematic item to aItemList to check if it's dangling state has changed.
Definition: sch_label.cpp:1104
VECTOR2I GetSchematicTextOffset(const RENDER_SETTINGS *aSettings) const override
This offset depends on the orientation, the type of text, and the area required to draw the associate...
Definition: sch_label.cpp:391
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:337
bool Replace(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) override
Perform a text replace using the find and replace criteria in aSearchData on items that support text ...
Definition: sch_label.cpp:926
double Similarity(const SCH_ITEM &aItem) const override
Return a measure of how likely the other object is to represent the same object.
Definition: sch_label.cpp:600
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_label.cpp:1456
SCH_LABEL(const VECTOR2I &aPos=VECTOR2I(0, 0), const wxString &aText=wxEmptyString)
Definition: sch_label.cpp:1418
const BOX2I GetBodyBoundingBox() const override
Return the bounding box of the label only, without taking in account its fields.
Definition: sch_label.cpp:1427
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_label.cpp:1463
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
int GetVirtualPageNumber() const
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:57
bool ResolveTextVar(const SCH_SHEET_PATH *aPath, wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the sheet.
Definition: sch_sheet.cpp:237
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_text.h:104
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_text.cpp:88
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_label.cpp:2072
VECTOR2I GetPosition() const override
Definition: sch_text.h:134
virtual void Rotate90(bool aClockwise)
Definition: sch_text.cpp:109
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_text.cpp:79
virtual double Similarity(const SCH_ITEM &aItem) const override
Return a measure of how likely the other object is to represent the same object.
Definition: sch_text.cpp:445
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_text.cpp:131
int GetPenWidth() const override
Definition: sch_text.cpp:182
virtual void MirrorSpinStyle(bool aLeftRight)
Definition: sch_text.cpp:121
virtual bool operator==(const SCH_ITEM &aItem) const override
Definition: sch_text.cpp:428
int GetTextOffset(const RENDER_SETTINGS *aSettings=nullptr) const
Definition: sch_text.cpp:167
SPIN_STYLE MirrorX()
Mirror the label spin style across the X axis or simply swaps up and bottom.
Definition: sch_label.cpp:172
SPIN m_spin
Definition: sch_label.h:83
SPIN_STYLE()=default
SPIN_STYLE MirrorY()
Mirror the label spin style across the Y axis or simply swaps left and right.
Definition: sch_label.cpp:188
SPIN_STYLE RotateCCW()
Definition: sch_label.cpp:156
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:58
#define DEFAULT_LABEL_SIZE_RATIO
The offset of the pin name string from the end of the pin in mils.
#define DANGLING_SYMBOL_SIZE
< The size of the rectangle indicating an unconnected wire or label
#define _HKI(x)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:437
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:432
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:431
static constexpr EDA_ANGLE ANGLE_180
Definition: eda_angle.h:439
INSPECT_RESULT
Definition: eda_item.h:42
const INSPECTOR_FUNC & INSPECTOR
Definition: eda_item.h:78
void GRCircle(wxDC *aDC, const VECTOR2I &aPos, int aRadius, int aWidth, const COLOR4D &aColor)
Definition: gr_basic.cpp:357
void GRLine(wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:171
static const bool FILLED
Definition: gr_basic.cpp:30
void GRPoly(wxDC *DC, int n, const VECTOR2I *Points, bool Fill, int width, const COLOR4D &Color, const COLOR4D &BgColor)
Draw a new polyline and fill it if Fill, in drawing space.
Definition: gr_basic.cpp:341
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:165
void GRFilledCircle(wxDC *aDC, const VECTOR2I &aPos, int aRadius, int aWidth, const COLOR4D &aStrokeColor, const COLOR4D &aFillColor)
Draw a circle onto the drawing context aDC centered at the user coordinates (x,y).
Definition: gr_basic.cpp:369
@ NONE
Definition: kibis.h:54
@ LAYER_DANGLING
Definition: layer_ids.h:379
@ LAYER_DEVICE
Definition: layer_ids.h:368
@ LAYER_HIERLABEL
Definition: layer_ids.h:360
@ LAYER_GLOBLABEL
Definition: layer_ids.h:359
@ LAYER_BUS
Definition: layer_ids.h:356
@ LAYER_FIELDS
Definition: layer_ids.h:365
@ LAYER_LOCLABEL
Definition: layer_ids.h:358
@ LAYER_NETCLASS_REFS
Definition: layer_ids.h:367
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:393
@ LAYER_INTERSHEET_REFS
Definition: layer_ids.h:366
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
T MIRRORVAL(T aPoint, T aMirrorRef)
Returns the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:31
Message panel definition file.
wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
Definition: ui_common.cpp:210
void delete_matching(_Container &__c, _Value __value)
Covers for the horrifically named std::remove and std::remove_if (neither of which remove anything).
Definition: kicad_algo.h:165
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:424
see class PGM_BASE
#define TYPE_HASH(x)
Definition: property.h:67
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:755
#define REGISTER_TYPE(x)
Definition: property_mgr.h:366
CONNECTION_TYPE
@ NO_CONNECT_END
Definition: sch_item.h:77
@ SHEET_LABEL_END
Definition: sch_item.h:76
@ LABEL_END
Definition: sch_item.h:73
@ BUS_END
Definition: sch_item.h:70
@ PIN_END
Definition: sch_item.h:72
@ WIRE_END
Definition: sch_item.h:69
std::vector< SCH_ITEM * > SCH_ITEM_SET
Definition: sch_item.h:154
@ FIELDS_AUTOPLACED_AUTO
Definition: sch_item.h:61
static int TemplateIN_HI[]
Definition: sch_label.cpp:108
static int TemplateUNSPC_HI[]
Definition: sch_label.cpp:118
static int TemplateOUT_HN[]
Definition: sch_label.cpp:112
static int Template3STATE_HN[]
Definition: sch_label.cpp:127
static int TemplateBIDI_HN[]
Definition: sch_label.cpp:122
static int * TemplateShape[5][4]
Definition: sch_label.cpp:132
bool IncrementLabelMember(wxString &name, int aIncrement)
Definition: sch_label.cpp:50
static int TemplateIN_HN[]
Definition: sch_label.cpp:107
static int TemplateIN_BOTTOM[]
Definition: sch_label.cpp:110
static int TemplateUNSPC_HN[]
Definition: sch_label.cpp:117
static int Template3STATE_BOTTOM[]
Definition: sch_label.cpp:130
static int TemplateBIDI_BOTTOM[]
Definition: sch_label.cpp:125
static struct SCH_LABEL_DESC _SCH_LABEL_DESC
static int Template3STATE_UP[]
Definition: sch_label.cpp:129
static int TemplateOUT_UP[]
Definition: sch_label.cpp:114
static int TemplateOUT_HI[]
Definition: sch_label.cpp:113
static int TemplateUNSPC_UP[]
Definition: sch_label.cpp:119
static int TemplateUNSPC_BOTTOM[]
Definition: sch_label.cpp:120
static int TemplateOUT_BOTTOM[]
Definition: sch_label.cpp:115
static int Template3STATE_HI[]
Definition: sch_label.cpp:128
static int TemplateIN_UP[]
Definition: sch_label.cpp:109
wxString getElectricalTypeLabel(LABEL_FLAG_SHAPE aType)
Definition: sch_label.cpp:142
static int TemplateBIDI_UP[]
Definition: sch_label.cpp:124
static int TemplateBIDI_HI[]
Definition: sch_label.cpp:123
static struct SCH_DIRECTIVE_LABEL_DESC _SCH_DIRECTIVE_LABEL_DESC
FLAG_SHAPE
Definition: sch_label.h:118
LABEL_FLAG_SHAPE
Definition: sch_label.h:91
@ L_BIDI
Definition: sch_label.h:94
@ L_TRISTATE
Definition: sch_label.h:95
@ L_UNSPECIFIED
Definition: sch_label.h:96
@ L_OUTPUT
Definition: sch_label.h:93
@ L_INPUT
Definition: sch_label.h:92
LABEL_SHAPE
Definition: sch_label.h:109
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_NETNAME
Definition: string_utils.h:53
void ConvertMarkdown2Html(const wxString &aMarkdownInput, wxString &aHtmlOutput)
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
wxString replaceString
bool m_PDFPropertyPopups
Definition: sch_plotter.h:90
constexpr int delta
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:174
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:228
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:128
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_FIELD_T
Definition: typeinfo.h:159
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:158
@ SCH_LABEL_T
Definition: typeinfo.h:155
@ SCH_LOCATE_ANY_T
Definition: typeinfo.h:187
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:157
@ SCH_LABEL_LOCATE_ANY_T
Definition: typeinfo.h:179
@ SCH_LABEL_LOCATE_WIRE_T
Definition: typeinfo.h:180
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:161
@ SCH_LABEL_LOCATE_BUS_T
Definition: typeinfo.h:181
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:156
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588