KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_track_via_properties.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) 2015 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
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 <core/kicad_algo.h>
31#include <footprint.h>
32#include <pad.h>
33#include <pcb_track.h>
34#include <confirm.h>
35#include <kidialog.h>
37#include <board_commit.h>
38#include <magic_enum.hpp>
39#include <macros.h>
40
41
43 const IPC4761_CONFIGURATION& aOther ) const
44{
45 return ( tent == aOther.tent ) && ( plug == aOther.plug ) && ( cover == aOther.cover )
46 && ( cap == aOther.cap ) && ( fill == aOther.fill );
47}
48
49
51 const PCB_SELECTION& aItems ) :
53 m_frame( aParent ),
54 m_items( aItems ),
57 m_trackEndX( aParent, m_TrackEndXLabel, m_TrackEndXCtrl, nullptr ),
61 m_viaX( aParent, m_ViaXLabel, m_ViaXCtrl, nullptr ),
70 m_tracks( false ),
71 m_vias( false ),
73{
75
76 wxASSERT( !m_items.Empty() );
77
78 m_legacyTeardropsIcon->SetBitmap( KiBitmapBundle( BITMAPS::dialog_warning ) );
80
81 m_bitmapTeardrop->SetBitmap( KiBitmapBundle( BITMAPS::teardrop_sizes ) );
82
83 m_teardropHDPercent.SetUnits( EDA_UNITS::PERCENT );
84 m_teardropLenPercent.SetUnits( EDA_UNITS::PERCENT );
85 m_teardropWidthPercent.SetUnits( EDA_UNITS::PERCENT );
86
87 m_minTrackWidthHint->SetFont( KIUI::GetInfoFont( this ).Italic() );
88
89 // Configure display origin transforms
96
97 VIATYPE viaType = VIATYPE::NOT_DEFINED;
98
103
106 m_ViaStartLayer->SetBoardFrame( aParent );
108
111 m_ViaEndLayer->SetBoardFrame( aParent );
113
114 wxFont infoFont = KIUI::GetSmallInfoFont( this );
115 m_techLayersLabel->SetFont( infoFont );
116
117 bool nets = false;
118 int net = 0;
119 bool hasLocked = false;
120 bool hasUnlocked = false;
121
122 // Start and end layers of vias
123 // if at least 2 vias do not have the same start or the same end layer
124 // the layers will be set as undefined
125 int selection_first_layer = -1;
126 int selection_last_layer = -1;
127
128 // The selection layer for tracks
129 int track_selection_layer = -1;
130
131 auto getAnnularRingSelection = []( const PCB_VIA* via ) -> int
132 {
133 switch( via->Padstack().UnconnectedLayerMode() )
134 {
135 default:
140 }
141 };
142
143 for( auto& preset : magic_enum::enum_values<IPC4761_PRESET>() )
144 {
145 if( preset >= IPC4761_PRESET::CUSTOM )
146 continue;
147
148 const auto& name_it = m_IPC4761Names.find( preset );
149
150 wxString name = _( "Unknown choice" );
151
152 if( name_it != m_IPC4761Names.end() )
153 name = name_it->second;
154
155 m_protectionFeatures->AppendString( name );
156 }
157
158 auto getProtectionSurface = []( const std::optional<bool>& front,
159 const std::optional<bool>& back ) -> IPC4761_SURFACE
160 {
162
163 if( !front.has_value() )
165 else if( front.value() )
167 else
168 value = IPC4761_SURFACE::NONE;
169
170 if( !back.has_value() )
171 {
172 if( value == IPC4761_SURFACE::FROM_RULES )
174 }
175 else if( back.value() )
176 {
177 if( value == IPC4761_SURFACE::FRONT )
179 else if( value == IPC4761_SURFACE::NONE )
181 }
182 else
183 {
184 if( value == IPC4761_SURFACE::FRONT )
186 else if( value == IPC4761_SURFACE::NONE )
188 }
189
191 };
192
193 auto getProtectionDrill = []( const std::optional<bool>& drill ) -> IPC4761_DRILL
194 {
195 if( !drill.has_value() )
197 if( drill.value() )
198 return IPC4761_DRILL::SET;
199
201 };
202
203 auto getViaConfiguration = [&]( const PCB_VIA* via ) -> IPC4761_PRESET
204 {
206 config.tent = getProtectionSurface( via->Padstack().FrontOuterLayers().has_solder_mask,
207 via->Padstack().BackOuterLayers().has_solder_mask );
208
209 config.cover = getProtectionSurface( via->Padstack().FrontOuterLayers().has_covering,
210 via->Padstack().BackOuterLayers().has_covering );
211
212 config.plug = getProtectionSurface( via->Padstack().FrontOuterLayers().has_plugging,
213 via->Padstack().BackOuterLayers().has_plugging );
214
215 config.cap = getProtectionDrill( via->Padstack().Drill().is_capped );
216
217 config.fill = getProtectionDrill( via->Padstack().Drill().is_filled );
218
219 for( const auto& [preset, configuration] : m_IPC4761Presets )
220 {
221 if( configuration == config )
222 return preset;
223 }
224
226 };
227
228 // Look for values that are common for every item that is selected
229 for( EDA_ITEM* item : m_items )
230 {
231 if( !nets )
232 {
233 net = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode();
234 nets = true;
235 }
236 else if( net != static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode() )
237 {
238 net = -1;
239 }
240
241 switch( item->Type() )
242 {
243 case PCB_TRACE_T:
244 case PCB_ARC_T:
245 {
246 const PCB_TRACK* t = static_cast<const PCB_TRACK*>( item );
247
248 if( !m_tracks ) // first track in the list
249 {
255 track_selection_layer = t->GetLayer();
256 m_trackHasSolderMask->SetValue ( t->HasSolderMask() );
257
258 if( t->GetLocalSolderMaskMargin().has_value() )
260 else
261 m_trackMaskMargin.SetValue( wxEmptyString );
262
263 m_tracks = true;
264 }
265 else // check if values are the same for every selected track
266 {
267 if( m_trackStartX.GetValue() != t->GetStartX() )
269
270 if( m_trackStartY.GetValue() != t->GetStartY() )
272
273 if( m_trackEndX.GetValue() != t->GetEndX() )
275
276 if( m_trackEndY.GetValue() != t->GetEndY() )
278
279 if( m_trackWidth.GetValue() != t->GetWidth() )
281
282 if( track_selection_layer != t->GetLayer() )
283 track_selection_layer = UNDEFINED_LAYER;
284
285 if( m_trackHasSolderMask->GetValue() != t->HasSolderMask() )
286 m_trackHasSolderMask->Set3StateValue( wxCHK_UNDETERMINED );
287
290 }
291
292 if( t->IsLocked() )
293 hasLocked = true;
294 else
295 hasUnlocked = true;
296
297 break;
298 }
299
300 case PCB_VIA_T:
301 {
302 PCB_VIA* v = static_cast<PCB_VIA*>( item );
303
304 if( !m_vias ) // first via in the list
305 {
308 m_viaStack = std::make_unique<PADSTACK>( v->Padstack() );
311 m_vias = true;
312 viaType = v->GetViaType();
313 m_viaNotFree->SetValue( !v->GetIsFree() );
314 m_annularRingsCtrl->SetSelection( getAnnularRingSelection( v ) );
315
316 selection_first_layer = v->TopLayer();
317 selection_last_layer = v->BottomLayer();
318
319 m_cbTeardrops->SetValue( v->GetTeardropParams().m_Enabled );
327
328 IPC4761_PRESET preset = getViaConfiguration( v );
329
330 if( preset >= IPC4761_PRESET::CUSTOM )
331 {
332 m_protectionFeatures->SetSelection(
334 }
335 else
336 {
337 m_protectionFeatures->SetSelection( static_cast<int>( preset ) );
338 }
339 }
340 else // check if values are the same for every selected via
341 {
342 if( m_viaX.GetValue() != v->GetPosition().x )
344
345 if( m_viaY.GetValue() != v->GetPosition().y )
347
350
351 if( m_viaDrill.GetValue() != v->GetDrillValue() )
353
354 if( viaType != v->GetViaType() )
355 viaType = VIATYPE::NOT_DEFINED;
356
357 if( v->GetIsFree() != !m_viaNotFree->GetValue() )
358 m_viaNotFree->Set3StateValue( wxCHK_UNDETERMINED );
359
360 if( selection_first_layer != v->TopLayer() )
361 selection_first_layer = UNDEFINED_LAYER;
362
363 if( selection_last_layer != v->BottomLayer() )
364 selection_last_layer = UNDEFINED_LAYER;
365
366 if( m_annularRingsCtrl->GetSelection() != getAnnularRingSelection( v ) )
367 {
368 if( m_annularRingsCtrl->GetStrings().size() < 4 )
370
371 m_annularRingsCtrl->SetSelection( 3 );
372 }
373
374 if( m_cbTeardrops->GetValue() != v->GetTeardropParams().m_Enabled )
375 m_cbTeardrops->Set3StateValue( wxCHK_UNDETERMINED );
376
378 m_cbTeardropsUseNextTrack->Set3StateValue( wxCHK_UNDETERMINED );
379
382
385
388
391
394
395
396 if( static_cast<int>( getViaConfiguration( v ) )
397 != m_protectionFeatures->GetSelection() )
398 {
399 m_protectionFeatures->SetSelection(
401 }
402 }
403
404 if( v->IsLocked() )
405 hasLocked = true;
406 else
407 hasUnlocked = true;
408
409 break;
410 }
411
412 default:
413 {
414 UNIMPLEMENTED_FOR( item->GetClass() );
415 break;
416 }
417 }
418 }
419
420 if( m_tracks )
421 {
422 // Set the track layer selection state:
423 if( track_selection_layer == UNDEFINED_LAYER )
424 {
427 }
428
429 m_TrackLayerCtrl->SetLayerSelection( track_selection_layer );
430 }
431
432 // Set the vias layers selections state:
433 if( m_vias )
434 {
435 if( selection_first_layer == UNDEFINED_LAYER )
436 {
439 }
440
441 m_ViaStartLayer->SetLayerSelection( selection_first_layer );
442
443 if( selection_last_layer == UNDEFINED_LAYER )
444 {
447 }
448
449 m_ViaEndLayer->SetLayerSelection( selection_last_layer );
450 }
451
452 m_netSelector->SetNetInfo( &aParent->GetBoard()->GetNetInfo() );
453
454 if ( net >= 0 )
455 {
457 }
458 else
459 {
462 }
463
464 wxASSERT( m_tracks || m_vias );
465
466 if( m_vias )
467 {
468 if( m_viaNotFree->GetValue() && !m_tracks )
469 {
470 // Disable net selector to re-inforce meaning of "Automatically update via nets",
471 // but not when tracks are also selected as then things get harder if you want to
472 // update all the nets to match.
473 m_netSelectorLabel->Disable();
474 m_netSelector->Disable();
475 }
476
477 int viaSelection = wxNOT_FOUND;
478
479 // 0 is the netclass place-holder
480 for( unsigned ii = 1; ii < aParent->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
481 {
482 VIA_DIMENSION* viaDimension = &aParent->GetDesignSettings().m_ViasDimensionsList[ii];
483 wxString msg = m_frame->StringFromValue( viaDimension->m_Diameter )
484 + wxT( " / " )
485 + m_frame->StringFromValue( viaDimension->m_Drill );
486 m_predefinedViaSizesCtrl->Append( msg, viaDimension );
487
488 if( viaSelection == wxNOT_FOUND
489 && m_viaDiameter.GetValue() == viaDimension->m_Diameter
490 && m_viaDrill.GetValue() == viaDimension->m_Drill )
491 {
492 viaSelection = ii - 1;
493 }
494 }
495
496 m_predefinedViaSizesCtrl->SetSelection( viaSelection );
498
499 m_ViaTypeChoice->Enable();
500
501 switch( viaType )
502 {
503 case VIATYPE::THROUGH: m_ViaTypeChoice->SetSelection( 0 ); break;
504 case VIATYPE::MICROVIA: m_ViaTypeChoice->SetSelection( 1 ); break;
505 case VIATYPE::BLIND_BURIED: m_ViaTypeChoice->SetSelection( 2 ); break;
506 case VIATYPE::NOT_DEFINED: m_ViaTypeChoice->SetSelection( wxNOT_FOUND ); break;
507 }
508
509 m_ViaStartLayer->Enable( viaType != VIATYPE::THROUGH );
510 m_ViaEndLayer->Enable( viaType != VIATYPE::THROUGH );
511
512 m_annularRingsLabel->Show( getLayerDepth() > 1 );
513 m_annularRingsCtrl->Show( getLayerDepth() > 1 );
514 m_annularRingsCtrl->Enable( true );
515
517 }
518 else
519 {
520 m_viaNotFree->Hide();
521 m_MainSizer->Hide( m_sbViaSizer, true );
522 }
523
524 if( m_tracks )
525 {
526 int widthSelection = wxNOT_FOUND;
527
528 // 0 is the netclass place-holder
529 for( unsigned ii = 1; ii < aParent->GetDesignSettings().m_TrackWidthList.size(); ii++ )
530 {
531 int width = aParent->GetDesignSettings().m_TrackWidthList[ii];
532 wxString msg = m_frame->StringFromValue( width );
533 m_predefinedTrackWidthsCtrl->Append( msg );
534
535 if( widthSelection == wxNOT_FOUND && m_trackWidth.GetValue() == width )
536 widthSelection = ii - 1;
537 }
538
539 m_predefinedTrackWidthsCtrl->SetSelection( widthSelection );
541
542 wxCommandEvent event;
543 onTrackEdit( event );
544 }
545 else
546 {
547 m_MainSizer->Hide( m_sbTrackSizer, true );
548 }
549
550 if( hasLocked && hasUnlocked )
551 m_lockedCbox->Set3StateValue( wxCHK_UNDETERMINED );
552 else if( hasLocked )
553 m_lockedCbox->Set3StateValue( wxCHK_CHECKED );
554 else
555 m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
556
557 if( m_tracks )
559 else if( m_netSelector->IsEnabled() )
561 else
563
565
566 m_frame->Bind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
567 m_netSelector->Bind( FILTERED_ITEM_SELECTED, &DIALOG_TRACK_VIA_PROPERTIES::onNetSelector, this );
568
569 // Now all widgets have the size fixed, call FinishDialogSettings
571}
572
573
575{
576 m_frame->Unbind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
577}
578
579
581{
582 if( m_vias )
583 {
584 int viaSel = m_predefinedViaSizesCtrl->GetSelection();
585
587
588 // 0 is the netclass place-holder
589 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
590 {
592 wxString msg = m_frame->StringFromValue( viaDimension->m_Diameter )
593 + wxT( " / " )
594 + m_frame->StringFromValue( viaDimension->m_Drill );
595 m_predefinedViaSizesCtrl->Append( msg, viaDimension );
596 }
597
598 m_predefinedViaSizesCtrl->SetSelection( viaSel );
600 }
601
602 if( m_tracks )
603 {
604 int trackSel = m_predefinedTrackWidthsCtrl->GetSelection();
605
607
608 // 0 is the netclass place-holder
609 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_TrackWidthList.size(); ii++ )
610 {
611 int width = m_frame->GetDesignSettings().m_TrackWidthList[ii];
612 wxString msg = m_frame->StringFromValue( width );
613 m_predefinedTrackWidthsCtrl->Append( msg );
614 }
615
616 m_predefinedTrackWidthsCtrl->SetSelection( trackSel );
618 }
619
620 aEvent.Skip();
621}
622
623
624bool DIALOG_TRACK_VIA_PROPERTIES::confirmShortingNets( int aNet, const std::set<int>& shortingNets )
625{
626 wxString msg;
627
628 if( shortingNets.size() == 1 )
629 {
630 msg.Printf( _( "Applying these changes will short net %s with %s." ),
631 m_netSelector->GetValue(),
632 m_frame->GetBoard()->FindNet( *shortingNets.begin() )->GetNetname() );
633 }
634 else
635 {
636 msg.Printf( _( "Applying these changes will short net %s with other nets." ),
637 m_netSelector->GetValue() );
638 }
639
640 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
641 dlg.SetOKCancelLabels( _( "Apply Anyway" ), _( "Cancel Changes" ) );
642 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
643
644 return dlg.ShowModal() == wxID_OK;
645}
646
647
648bool DIALOG_TRACK_VIA_PROPERTIES::confirmPadChange( const std::set<PAD*>& changingPads )
649{
650 wxString msg;
651
652 if( changingPads.size() == 1 )
653 {
654 PAD* pad = *changingPads.begin();
655 msg.Printf( _( "Changing the net will also update %s pad %s to %s." ),
656 pad->GetParentFootprint()->GetReference(),
657 pad->GetNumber(),
658 m_netSelector->GetValue() );
659 }
660 else if( changingPads.size() == 2 )
661 {
662 PAD* pad1 = *changingPads.begin();
663 PAD* pad2 = *( ++changingPads.begin() );
664 msg.Printf( _( "Changing the net will also update %s pad %s and %s pad %s to %s." ),
666 pad1->GetNumber(),
668 pad2->GetNumber(),
669 m_netSelector->GetValue() );
670 }
671 else
672 {
673 msg.Printf( _( "Changing the net will also update %lu connected pads to %s." ),
674 static_cast<unsigned long>( changingPads.size() ),
675 m_netSelector->GetValue() );
676 }
677
678 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
679 dlg.SetOKCancelLabels( _( "Change Nets" ), _( "Leave Nets Unchanged" ) );
680 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
681
682 return dlg.ShowModal() == wxID_OK;
683}
684
685
687{
688 std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_frame->GetBoard()->GetConnectivity();
689 std::vector<PCB_TRACK*> selected_tracks;
690 std::set<PCB_TRACK*> connected_tracks;
691
692 for( EDA_ITEM* item : m_items )
693 {
694 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
695 selected_tracks.push_back( track );
696 }
697
698 for( PCB_TRACK* selected_track : selected_tracks )
699 {
700 for( BOARD_CONNECTED_ITEM* connected_item : connectivity->GetConnectedItems( selected_track ) )
701 {
702 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( connected_item ) )
703 connected_tracks.insert( track );
704 }
705 }
706
707 // Check for malformed data ONLY; design rules and constraints are the business of DRC.
708
709 if( m_vias )
710 {
711 // TODO: This needs to move into the via class, not the dialog
712
714 || !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
715 {
716 return false;
717 }
718
719 if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate()
720 && m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate()
722 {
723 DisplayError( GetParent(), _( "Via hole size must be smaller than via diameter" ) );
724 m_ViaDrillCtrl->SelectAll();
725 m_ViaDrillCtrl->SetFocus();
726 return false;
727 }
728
731 {
732 DisplayError( GetParent(), _( "Via start layer and end layer cannot be the same" ) );
733 return false;
734 }
735
737 {
738 int diameter = m_viaDiameter.GetValue();
739 m_viaStack->SetSize( { diameter, diameter }, m_editLayer );
740 }
741 }
742
743 if( m_tracks )
744 {
745 if( !m_trackWidth.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
746 return false;
747 }
748
749 // If we survived that, then save the changes:
750 //
751 // We don't bother with updating the nets at this point as it will be useless (any connected
752 // pads will simply drive their existing nets back onto the track segments and vias).
753
754 BOARD_COMMIT commit( m_frame );
755 bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
756 bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;
757
758 for( PCB_TRACK* track : selected_tracks )
759 {
760 commit.Modify( track );
761
762 switch( track->Type() )
763 {
764 case PCB_TRACE_T:
765 case PCB_ARC_T:
766 {
767 wxASSERT( m_tracks );
768
770 track->SetStartX( m_trackStartX.GetIntValue() );
771
773 track->SetStartY( m_trackStartY.GetIntValue() );
774
776 track->SetEndX( m_trackEndX.GetIntValue() );
777
779 track->SetEndY( m_trackEndY.GetIntValue() );
780
782 track->SetWidth( m_trackWidth.GetIntValue() );
783
784 int layer = m_TrackLayerCtrl->GetLayerSelection();
785
786 if( layer != UNDEFINED_LAYER )
787 track->SetLayer( (PCB_LAYER_ID) layer );
788
789 if ( m_trackHasSolderMask->Get3StateValue() != wxCHK_UNDETERMINED )
790 track->SetHasSolderMask( m_trackHasSolderMask->GetValue() );
791
793 {
795 track->SetLocalSolderMaskMargin( {} );
796 else
797 track->SetLocalSolderMaskMargin( m_trackMaskMargin.GetIntValue() );
798 }
799
800 if( changeLock )
801 track->SetLocked( setLock );
802
803 break;
804 }
805
806 case PCB_VIA_T:
807 {
808 wxASSERT( m_vias );
809 PCB_VIA* via = static_cast<PCB_VIA*>( track );
810
811 if( !m_viaX.IsIndeterminate() )
812 via->SetPosition( VECTOR2I( m_viaX.GetIntValue(), via->GetPosition().y ) );
813
814 if( !m_viaY.IsIndeterminate() )
815 via->SetPosition( VECTOR2I( via->GetPosition().x, m_viaY.GetIntValue() ) );
816
817 if( m_viaNotFree->Get3StateValue() != wxCHK_UNDETERMINED )
818 via->SetIsFree( !m_viaNotFree->GetValue() );
819
821 via->SetPadstack( *m_viaStack );
822
823 switch( m_ViaTypeChoice->GetSelection() )
824 {
825 case 0: via->SetViaType( VIATYPE::THROUGH ); break;
826 case 1: via->SetViaType( VIATYPE::MICROVIA ); break;
827 case 2: via->SetViaType( VIATYPE::BLIND_BURIED ); break;
828 default: break;
829 }
830
831 PCB_LAYER_ID startLayer = static_cast<PCB_LAYER_ID>( m_ViaStartLayer->GetLayerSelection() );
832 PCB_LAYER_ID endLayer = static_cast<PCB_LAYER_ID>( m_ViaEndLayer->GetLayerSelection() );
833
834 if( startLayer != UNDEFINED_LAYER )
835 {
836 m_viaStack->Drill().start = startLayer;
837 via->SetTopLayer( startLayer );
838 }
839
840 if( endLayer != UNDEFINED_LAYER )
841 {
842 m_viaStack->Drill().end = endLayer;
843 via->SetBottomLayer( endLayer );
844 }
845
846 via->SanitizeLayers();
847
848 switch( m_annularRingsCtrl->GetSelection() )
849 {
850 case 0:
851 via->Padstack().SetUnconnectedLayerMode(
853 break;
854 case 1:
855 via->Padstack().SetUnconnectedLayerMode(
857 break;
858 case 2:
859 via->Padstack().SetUnconnectedLayerMode(
861 break;
862 case 3:
863 via->Padstack().SetUnconnectedLayerMode(
865 break;
866 default:
867 break;
868 }
869
870
872 via->SetDrill( m_viaDrill.GetIntValue() );
873
874 TEARDROP_PARAMETERS* targetParams = &via->GetTeardropParams();
875
876 if( m_cbTeardrops->Get3StateValue() != wxCHK_UNDETERMINED )
877 targetParams->m_Enabled = m_cbTeardrops->GetValue();
878
879 if( m_cbTeardropsUseNextTrack->Get3StateValue() != wxCHK_UNDETERMINED )
880 targetParams->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
881
883 targetParams->m_TdMaxLen = m_teardropMaxLen.GetIntValue();
884
887
889 targetParams->m_BestLengthRatio = m_teardropLenPercent.GetDoubleValue() / 100.0;
890
892 targetParams->m_BestWidthRatio =
894
897
898 if( m_curvedEdges->Get3StateValue() != wxCHK_UNDETERMINED )
899 targetParams->m_CurvedEdges = m_curvedEdges->GetValue();
900
901 if( changeLock )
902 via->SetLocked( setLock );
903
904 auto setSurfaceProtection =
905 [&]( std::optional<bool>& aFront, std::optional<bool>& aBack, IPC4761_SURFACE aProtection )
906 {
907 switch( aProtection )
908 {
910 aFront.reset();
911 aBack.reset();
912 break;
914 aFront = false;
915 aBack = false;
916 break;
918 aFront = true;
919 aBack = false;
920 break;
922 aFront = false;
923 aBack = true;
924 break;
926 aFront = true;
927 aBack = true;
928 break;
929 case IPC4761_SURFACE::CUSTOM: return;
930 }
931 };
932
933 auto setDrillProtection =
934 [&]( std::optional<bool>& aDrill, IPC4761_DRILL aProtection )
935 {
936 switch( aProtection )
937 {
938 case IPC4761_DRILL::FROM_RULES: aDrill.reset(); break;
939 case IPC4761_DRILL::NOT_SET: aDrill = false; break;
940 case IPC4761_DRILL::SET: aDrill = true; break;
941 }
942 };
943
944 IPC4761_PRESET selectedPreset = static_cast<IPC4761_PRESET>( m_protectionFeatures->GetSelection() );
945
946 if( selectedPreset < IPC4761_PRESET::CUSTOM ) // Do not change custom feaure list.
947 {
948 const IPC4761_CONFIGURATION config = m_IPC4761Presets.at( selectedPreset );
949
950 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_solder_mask,
951 via->Padstack().BackOuterLayers().has_solder_mask,
952 config.tent );
953
954 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_plugging,
955 via->Padstack().BackOuterLayers().has_plugging,
956 config.plug );
957
958 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_covering,
959 via->Padstack().BackOuterLayers().has_covering,
960 config.cover );
961
962 setDrillProtection( via->Padstack().Drill().is_filled, config.fill );
963
964 setDrillProtection( via->Padstack().Drill().is_capped, config.cap );
965 }
966
967 break;
968 }
969
970 default:
971 UNIMPLEMENTED_FOR( track->GetClass() );
972 break;
973 }
974 }
975
976 std::set<int> shortingNets;
977 int newNetCode = m_netSelector->GetSelectedNetcode();
978 std::set<PAD*> changingPads;
979
980 // Do NOT use the connectivity code here. It will propagate through zones, and we haven't
981 // refilled those yet so it's going to pick up a whole bunch of other nets any time the track
982 // width was increased.
983 auto collide =
985 {
986 for( PCB_LAYER_ID layer : LSET( a->GetLayerSet() & b->GetLayerSet() ) )
987 {
988 if( a->GetEffectiveShape( layer )->Collide( b->GetEffectiveShape( layer ).get() ) )
989 return true;
990 }
991
992 return false;
993 };
994
995 for( PCB_TRACK* track : connected_tracks )
996 {
997 for( PCB_TRACK* other : m_frame->GetBoard()->Tracks() )
998 {
999 if( other->GetNetCode() == track->GetNetCode() || other->GetNetCode() == newNetCode )
1000 continue;
1001
1002 if( collide( track, other ) )
1003 shortingNets.insert( other->GetNetCode() );
1004 }
1005
1006 for( FOOTPRINT* footprint : m_frame->GetBoard()->Footprints() )
1007 {
1008 for( PAD* pad : footprint->Pads() )
1009 {
1010 if( pad->GetNetCode() == newNetCode )
1011 continue;
1012
1013 if( collide( track, pad ) )
1014 {
1015 if( pad->GetNetCode() == track->GetNetCode() )
1016 changingPads.insert( pad );
1017 else
1018 shortingNets.insert( pad->GetNetCode() );
1019 }
1020 }
1021 }
1022 }
1023
1024 if( shortingNets.size() && !confirmShortingNets( newNetCode, shortingNets ) )
1025 {
1026 commit.Revert();
1027 return true;
1028 }
1029
1031 {
1032 if( changingPads.empty() || confirmPadChange( changingPads ) )
1033 {
1034 for( PCB_TRACK* track : selected_tracks )
1035 track->SetNetCode( newNetCode );
1036
1037 for( PAD* pad : changingPads )
1038 {
1039 commit.Modify( pad );
1040 pad->SetNetCode( newNetCode );
1041 }
1042 }
1043 }
1044
1045 commit.Push( _( "Edit Track/Via Properties" ) );
1046 return true;
1047}
1048
1049
1051{
1052 m_viaNotFree->SetValue( false );
1053}
1054
1055
1057{
1058 if( !m_tracks )
1059 {
1060 m_netSelectorLabel->Enable( !m_viaNotFree->GetValue() );
1061 m_netSelector->Enable( !m_viaNotFree->GetValue() );
1062 }
1063}
1064
1065
1067{
1068 m_TrackWidthCtrl->ChangeValue( m_predefinedTrackWidthsCtrl->GetStringSelection() );
1069 m_TrackWidthCtrl->SelectAll();
1070}
1071
1072
1073void DIALOG_TRACK_VIA_PROPERTIES::onWidthEdit( wxCommandEvent& aEvent )
1074{
1075 m_predefinedTrackWidthsCtrl->SetStringSelection( m_TrackWidthCtrl->GetValue() );
1076}
1077
1078
1079void DIALOG_TRACK_VIA_PROPERTIES::onViaSelect( wxCommandEvent& aEvent )
1080{
1081 VIA_DIMENSION* viaDimension = static_cast<VIA_DIMENSION*> ( aEvent.GetClientData() );
1082
1083 m_viaDiameter.ChangeValue( viaDimension->m_Diameter );
1084 m_viaDrill.ChangeValue( viaDimension->m_Drill );
1085}
1086
1087
1089{
1090 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in onPadstackModeChanged" );
1091
1092 switch( m_cbPadstackMode->GetSelection() )
1093 {
1094 default:
1095 case 0: m_viaStack->SetMode( PADSTACK::MODE::NORMAL ); break;
1096 case 1: m_viaStack->SetMode( PADSTACK::MODE::FRONT_INNER_BACK ); break;
1097 case 2: m_viaStack->SetMode( PADSTACK::MODE::CUSTOM ); break;
1098 }
1099
1101}
1102
1103
1105{
1106 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in onEditLayerChanged" );
1107
1108 // Save data from the previous layer
1110 {
1111 int diameter = m_viaDiameter.GetValue();
1112 m_viaStack->SetSize( { diameter, diameter }, m_editLayer );
1113 }
1114
1115 switch( m_viaStack->Mode() )
1116 {
1117 default:
1120 break;
1121
1123 switch( m_cbEditLayer->GetSelection() )
1124 {
1125 default:
1126 case 0: m_editLayer = F_Cu; break;
1127 case 1: m_editLayer = PADSTACK::INNER_LAYERS; break;
1128 case 2: m_editLayer = B_Cu; break;
1129 }
1130 break;
1131
1133 {
1134 int layer = m_cbEditLayer->GetSelection();
1135
1136 if( layer < 0 )
1137 layer = 0;
1138
1139 if( m_editLayerCtrlMap.contains( layer ) )
1140 m_editLayer = m_editLayerCtrlMap.at( layer );
1141 else
1142 m_editLayer = F_Cu;
1143 }
1144 }
1145
1146 // Load controls with the current layer
1148}
1149
1150
1152{
1153 // NOTE: synchronize changes here with DIALOG_PAD_PROPERTIES::afterPadstackModeChanged
1154
1155 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in afterPadstackModeChanged" );
1156 m_cbEditLayer->Clear();
1157
1158 BOARD* board = m_frame->GetBoard();
1159
1160 switch( m_viaStack->Mode() )
1161 {
1163 m_cbPadstackMode->SetSelection( 0 );
1164 m_cbEditLayer->Append( _( "All layers" ) );
1165 m_cbEditLayer->Disable();
1168 break;
1169
1171 {
1172 m_cbPadstackMode->SetSelection( 1 );
1173 m_cbEditLayer->Enable();
1174
1175 std::vector choices = {
1176 board->GetLayerName( F_Cu ),
1177 _( "Inner Layers" ),
1178 board->GetLayerName( B_Cu )
1179 };
1180
1181 m_cbEditLayer->Append( choices );
1182
1184 { 0, F_Cu },
1186 { 2, B_Cu }
1187 };
1188
1189 if( m_editLayer != F_Cu && m_editLayer != B_Cu )
1191
1192 break;
1193 }
1194
1196 {
1197 m_cbPadstackMode->SetSelection( 2 );
1198 m_cbEditLayer->Enable();
1199 LSET layers = LSET::AllCuMask() & board->GetEnabledLayers();
1200
1201 for( PCB_LAYER_ID layer : layers.UIOrder() )
1202 {
1203 int idx = m_cbEditLayer->Append( board->GetLayerName( layer ) );
1204 m_editLayerCtrlMap[idx] = layer;
1205 }
1206
1207 break;
1208 }
1209 }
1210
1211 for( const auto& [idx, layer] : m_editLayerCtrlMap )
1212 {
1213 if( layer == m_editLayer )
1214 {
1215 m_cbEditLayer->SetSelection( idx );
1216 break;
1217 }
1218 }
1219}
1220
1221
1223{
1224 int viaType = m_ViaTypeChoice->GetSelection();
1225
1226 if( viaType <= 0 )
1227 return m_frame->GetBoard()->GetCopperLayerCount() - 1;
1228
1229 int startLayer = m_ViaStartLayer->GetLayerSelection();
1230 int endLayer = m_ViaEndLayer->GetLayerSelection();
1231
1232 if( startLayer < 0 || endLayer < 0 )
1233 return m_frame->GetBoard()->GetCopperLayerCount() - 1;
1234 else
1235 return m_frame->GetBoard()->LayerDepth( ToLAYER_ID( startLayer ), ToLAYER_ID( endLayer ) );
1236}
1237
1238
1239void DIALOG_TRACK_VIA_PROPERTIES::onViaEdit( wxCommandEvent& aEvent )
1240{
1241 m_predefinedViaSizesCtrl->SetSelection( wxNOT_FOUND );
1242
1243 if( m_vias )
1244 {
1245 if( m_ViaTypeChoice->GetSelection() != 0 ) // check if selected type isn't through.
1246 {
1247 m_ViaStartLayer->Enable();
1248 m_ViaEndLayer->Enable();
1249 }
1250 else
1251 {
1254
1255 m_ViaStartLayer->Enable( false );
1256 m_ViaEndLayer->Enable( false );
1257 }
1258
1259 m_annularRingsLabel->Show( getLayerDepth() > 1 );
1260 m_annularRingsCtrl->Show( getLayerDepth() > 1 );
1261 m_annularRingsCtrl->Enable( true );
1262 }
1263}
1264
1265
1266void DIALOG_TRACK_VIA_PROPERTIES::onTrackEdit( wxCommandEvent& aEvent )
1267{
1268 bool externalCuLayer = m_TrackLayerCtrl->GetLayerSelection() == F_Cu
1270
1271 m_techLayersLabel->Enable( externalCuLayer );
1272 m_trackHasSolderMask->Enable( externalCuLayer );
1273
1274 bool showMaskMargin = externalCuLayer && m_trackHasSolderMask->GetValue();
1275
1276 m_trackMaskMarginCtrl->Enable( showMaskMargin );
1277 m_trackMaskMarginLabel->Enable( showMaskMargin );
1278 m_trackMaskMarginUnit->Enable( showMaskMargin );
1279}
1280
1281
1283{
1284 event.Enable( !m_frame->GetBoard()->LegacyTeardrops() );
1285}
1286
const char * name
Definition: DXF_plotter.cpp:62
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition: bitmap.cpp:110
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
virtual void Revert() override
Revert the commit by restoring the modified items state.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
TEARDROP_PARAMETERS & GetTeardropParams()
std::vector< int > m_TrackWidthList
std::vector< VIA_DIMENSION > m_ViasDimensionsList
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:232
bool IsLocked() const override
Definition: board_item.cpp:103
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: board_item.cpp:326
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:97
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition: board_item.h:252
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:317
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:934
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:2099
int GetCopperLayerCount() const
Definition: board.cpp:859
const FOOTPRINTS & Footprints() const
Definition: board.h:358
const TRACKS & Tracks() const
Definition: board.h:356
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition: board.cpp:680
int LayerDepth(PCB_LAYER_ID aStartLayer, PCB_LAYER_ID aEndLayer) const
Definition: board.cpp:895
bool LegacyTeardrops() const
Definition: board.h:1319
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition: board.cpp:907
std::shared_ptr< CONNECTIVITY_DATA > GetConnectivity() const
Return a list of missing connections between components/tracks.
Definition: board.h:522
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition: commit.h:107
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:75
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool m_useCalculatedSize
Definition: dialog_shim.h:240
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Class DIALOG_TRACK_VIA_PROPERTIES_BASE.
void onWidthEdit(wxCommandEvent &aEvent) override
void onUnitsChanged(wxCommandEvent &aEvent)
void onNetSelector(wxCommandEvent &aEvent)
void onWidthSelect(wxCommandEvent &aEvent) override
bool confirmShortingNets(int aNet, const std::set< int > &shortingNets)
const std::map< IPC4761_PRESET, IPC4761_CONFIGURATION > m_IPC4761Presets
const std::map< IPC4761_PRESET, wxString > m_IPC4761Names
void onTeardropsUpdateUi(wxUpdateUIEvent &event) override
void onPadstackModeChanged(wxCommandEvent &aEvent) override
void onViaEdit(wxCommandEvent &aEvent) override
std::map< int, PCB_LAYER_ID > m_editLayerCtrlMap
PCB_LAYER_ID m_editLayer
The currently-shown copper layer of the edited via(s)
void onViaSelect(wxCommandEvent &aEvent) override
void onEditLayerChanged(wxCommandEvent &aEvent) override
void onViaNotFreeClicked(wxCommandEvent &aEvent) override
DIALOG_TRACK_VIA_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, const PCB_SELECTION &aItems)
std::unique_ptr< PADSTACK > m_viaStack
Temporary padstack of the edited via(s)
bool confirmPadChange(const std::set< PAD * > &connectedPads)
void onTrackEdit(wxCommandEvent &aEvent) override
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:98
const wxString & GetReference() const
Definition: footprint.h:627
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: kidialog.h:50
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
Definition: kidialog.cpp:51
bool SetOKCancelLabels(const ButtonLabel &ok, const ButtonLabel &cancel) override
Definition: kidialog.h:60
int ShowModal() override
Definition: kidialog.cpp:95
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
LSEQ UIOrder() const
Return the copper, technical and user layers in the order shown in layer widget.
Definition: lset.cpp:733
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:610
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
Definition: lset.cpp:591
const wxString & GetNetname() const
Definition: netinfo.h:114
void SetNetInfo(const NETINFO_LIST *aNetInfoList)
bool IsIndeterminate()
int GetSelectedNetcode()
void SetIndeterminateString(const wxString &aString)
void SetSelectedNetcode(int aNetcode)
void SetIndeterminate()
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
Definition: padstack.h:125
@ NORMAL
Shape is the same on all layers.
@ CUSTOM
Shapes can be defined on arbitrary layers.
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition: padstack.h:145
static constexpr PCB_LAYER_ID INNER_LAYERS
! The layer identifier to use for "inner layers" on top/inner/bottom padstacks
Definition: padstack.h:148
Definition: pad.h:54
const wxString & GetNumber() const
Definition: pad.h:136
Common, abstract interface for edit frames.
BOARD * GetBoard() const
virtual BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Return the BOARD_DESIGN_SETTINGS for the open project.
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetUndefinedLayerName(const wxString &aName)
void SetNotAllowedLayerSet(const LSET &aMask)
bool HasSolderMask() const
Definition: pcb_track.h:176
int GetStartY() const
Definition: pcb_track.h:158
int GetEndX() const
Definition: pcb_track.h:163
std::optional< int > GetLocalSolderMaskMargin() const
Definition: pcb_track.h:179
int GetEndY() const
Definition: pcb_track.h:164
int GetStartX() const
Definition: pcb_track.h:157
virtual int GetWidth() const
Definition: pcb_track.h:146
bool GetIsFree() const
Check if the via is a free via (as opposed to one created on a track by the router).
Definition: pcb_track.h:704
PCB_LAYER_ID BottomLayer() const
Definition: pcb_track.cpp:1395
VECTOR2I GetPosition() const override
Definition: pcb_track.h:557
const PADSTACK & Padstack() const
Definition: pcb_track.h:459
int GetWidth() const override
Definition: pcb_track.cpp:379
PCB_LAYER_ID TopLayer() const
Definition: pcb_track.cpp:1389
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
Definition: pcb_track.cpp:628
VIATYPE GetViaType() const
Definition: pcb_track.h:451
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:115
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_Enabled
Flag to enable teardrops.
bool m_CurvedEdges
True if the teardrop should be curved.
EDA_UNITS GetUserUnits() const
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aValue in internal units into a united string.
int GetIntValue()
Definition: unit_binder.h:134
virtual long long int GetValue()
Return the current value in Internal Units.
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
virtual double GetDoubleValue()
Return the current value in Internal Units.
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
virtual void SetDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void ChangeValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void SetCoordType(ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
Set the current origin transform mode.
Definition: unit_binder.h:205
bool IsNull() const
Return true if the control holds no value (ie: empty string, not 0).
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:169
This file is part of the common library.
#define _(s)
@ ALL_LAYERS
This file is part of the common library.
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ B_Cu
Definition: layer_ids.h:65
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
@ F_Cu
Definition: layer_ids.h:64
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:744
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition: macros.h:96
KICOMMON_API wxString GetLabel(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
Definition: eda_units.cpp:180
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:156
KICOMMON_API wxFont GetSmallInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:162
#define GEOMETRY_MIN_SIZE
Definition: pcb_track.h:112
VIATYPE
Definition: pcb_track.h:66
bool collide(T aObject, U aAnotherObject, int aLayer, int aMinDistance)
Used by SHAPE_INDEX to implement Query().
Definition: shape_index.h:97
bool operator==(const IPC4761_CONFIGURATION &other) const
Container to handle a stock of specific vias each with unique diameter and drill sizes in the BOARD c...
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
#define INDETERMINATE_ACTION
Definition: ui_common.h:47
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition: ui_common.h:46