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
79 m_legacyTeardropsWarning->Show( m_frame->GetBoard()->LegacyTeardrops() );
80
82
86
87 m_minTrackWidthHint->SetFont( KIUI::GetInfoFont( this ).Italic() );
88
89 // Configure display origin transforms
96
97 m_TrackLayerCtrl->SetLayersHotkeys( false );
98 m_TrackLayerCtrl->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
99 m_TrackLayerCtrl->SetBoardFrame( aParent );
100 m_TrackLayerCtrl->Resync();
101
102 m_ViaStartLayer->SetLayersHotkeys( false );
103 m_ViaStartLayer->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
104 m_ViaStartLayer->SetBoardFrame( aParent );
105 m_ViaStartLayer->Resync();
106
107 m_ViaEndLayer->SetLayersHotkeys( false );
108 m_ViaEndLayer->SetNotAllowedLayerSet( LSET::AllNonCuMask() );
109 m_ViaEndLayer->SetBoardFrame( aParent );
110 m_ViaEndLayer->Resync();
111
112 wxFont infoFont = KIUI::GetSmallInfoFont( this );
113 m_techLayersLabel->SetFont( infoFont );
114
115 m_frame->Bind( EDA_EVT_UNITS_CHANGED, &DIALOG_TRACK_VIA_PROPERTIES::onUnitsChanged, this );
116 m_netSelector->Bind( FILTERED_ITEM_SELECTED, &DIALOG_TRACK_VIA_PROPERTIES::onNetSelector, this );
117
119}
120
121
127
128
130{
131 // Setting widgets states/values must be in TransferDataToWindow, not in CTor
132 // otherwise states/values are overwritten by the DIALOG_SHIM::TransferDataToWindow() config values
133 bool nets = false;
134 int net = 0;
135 bool hasLocked = false;
136 bool hasUnlocked = false;
138
139 // Start and end layers of vias
140 // if at least 2 vias do not have the same start or the same end layer
141 // the layers will be set as undefined
142 int selection_first_layer = -1;
143 int selection_last_layer = -1;
144
145 // The selection layer for tracks
146 int track_selection_layer = -1;
147
148 auto getAnnularRingSelection = []( const PCB_VIA* via ) -> int
149 {
150 switch( via->Padstack().UnconnectedLayerMode() )
151 {
152 default:
157 }
158 };
159
160 for( auto& preset : magic_enum::enum_values<IPC4761_PRESET>() )
161 {
162 if( preset >= IPC4761_PRESET::CUSTOM )
163 continue;
164
165 const auto& name_it = m_IPC4761Names.find( preset );
166
167 wxString name = _( "Unknown choice" );
168
169 if( name_it != m_IPC4761Names.end() )
170 name = name_it->second;
171
172 m_protectionFeatures->AppendString( name );
173 }
174
175 auto getProtectionSurface = []( const std::optional<bool>& front,
176 const std::optional<bool>& back ) -> IPC4761_SURFACE
177 {
179
180 if( !front.has_value() )
182 else if( front.value() )
184 else
185 value = IPC4761_SURFACE::NONE;
186
187 if( !back.has_value() )
188 {
189 if( value == IPC4761_SURFACE::FROM_RULES )
191 }
192 else if( back.value() )
193 {
194 if( value == IPC4761_SURFACE::FRONT )
196 else if( value == IPC4761_SURFACE::NONE )
198 }
199 else
200 {
201 if( value == IPC4761_SURFACE::FRONT )
203 else if( value == IPC4761_SURFACE::NONE )
205 }
206
208 };
209
210 auto getProtectionDrill = []( const std::optional<bool>& drill ) -> IPC4761_DRILL
211 {
212 if( !drill.has_value() )
214 if( drill.value() )
215 return IPC4761_DRILL::SET;
216
218 };
219
220 auto getViaConfiguration = [&]( const PCB_VIA* via ) -> IPC4761_PRESET
221 {
223 config.tent = getProtectionSurface( via->Padstack().FrontOuterLayers().has_solder_mask,
224 via->Padstack().BackOuterLayers().has_solder_mask );
225
226 config.cover = getProtectionSurface( via->Padstack().FrontOuterLayers().has_covering,
227 via->Padstack().BackOuterLayers().has_covering );
228
229 config.plug = getProtectionSurface( via->Padstack().FrontOuterLayers().has_plugging,
230 via->Padstack().BackOuterLayers().has_plugging );
231
232 config.cap = getProtectionDrill( via->Padstack().Drill().is_capped );
233
234 config.fill = getProtectionDrill( via->Padstack().Drill().is_filled );
235
236 for( const auto& [preset, configuration] : m_IPC4761Presets )
237 {
238 if( configuration == config )
239 return preset;
240 }
241
243 };
244
245 // Look for values that are common for every item that is selected
246 for( EDA_ITEM* item : m_items )
247 {
248 if( !nets )
249 {
250 net = static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode();
251 nets = true;
252 }
253 else if( net != static_cast<BOARD_CONNECTED_ITEM*>( item )->GetNetCode() )
254 {
255 net = -1;
256 }
257
258 switch( item->Type() )
259 {
260 case PCB_TRACE_T:
261 case PCB_ARC_T:
262 {
263 const PCB_TRACK* t = static_cast<const PCB_TRACK*>( item );
264
265 if( !m_tracks ) // first track in the list
266 {
267 m_trackStartX.SetValue( t->GetStartX() );
268 m_trackStartY.SetValue( t->GetStartY() );
269 m_trackEndX.SetValue( t->GetEndX() );
270 m_trackEndY.SetValue( t->GetEndY() );
271 m_trackWidth.SetValue( t->GetWidth() );
272 track_selection_layer = t->GetLayer();
273 m_trackHasSolderMask->SetValue ( t->HasSolderMask() );
274
275 if( t->GetLocalSolderMaskMargin().has_value() )
276 m_trackMaskMargin.SetValue( t->GetLocalSolderMaskMargin().value() );
277 else
278 m_trackMaskMargin.SetValue( wxEmptyString );
279
280 m_tracks = true;
281 }
282 else // check if values are the same for every selected track
283 {
284 if( m_trackStartX.GetValue() != t->GetStartX() )
286
287 if( m_trackStartY.GetValue() != t->GetStartY() )
289
290 if( m_trackEndX.GetValue() != t->GetEndX() )
292
293 if( m_trackEndY.GetValue() != t->GetEndY() )
295
296 if( m_trackWidth.GetValue() != t->GetWidth() )
298
299 if( track_selection_layer != t->GetLayer() )
300 track_selection_layer = UNDEFINED_LAYER;
301
302 if( m_trackHasSolderMask->GetValue() != t->HasSolderMask() )
303 m_trackHasSolderMask->Set3StateValue( wxCHK_UNDETERMINED );
304
305 if( m_trackMaskMargin.GetValue() != t->GetLocalSolderMaskMargin() )
307 }
308
309 if( t->IsLocked() )
310 hasLocked = true;
311 else
312 hasUnlocked = true;
313
314 break;
315 }
316
317 case PCB_VIA_T:
318 {
319 PCB_VIA* v = static_cast<PCB_VIA*>( item );
320
321 if( !m_vias ) // first via in the list
322 {
323 m_viaX.SetValue( v->GetPosition().x );
324 m_viaY.SetValue( v->GetPosition().y );
325 m_viaStack = std::make_unique<PADSTACK>( v->Padstack() );
326 m_viaDiameter.SetValue( v->GetWidth( m_editLayer ) );
327 m_viaDrill.SetValue( v->GetDrillValue() );
328 m_vias = true;
329 viaType = v->GetViaType();
330 m_viaNotFree->SetValue( !v->GetIsFree() );
331 m_annularRingsCtrl->SetSelection( getAnnularRingSelection( v ) );
332
333 selection_first_layer = v->TopLayer();
334 selection_last_layer = v->BottomLayer();
335
336 m_cbTeardrops->SetValue( v->GetTeardropParams().m_Enabled );
340 m_teardropLenPercent.SetDoubleValue( v->GetTeardropParams().m_BestLengthRatio*100.0 );
341 m_teardropWidthPercent.SetDoubleValue( v->GetTeardropParams().m_BestWidthRatio*100.0 );
344
345 IPC4761_PRESET preset = getViaConfiguration( v );
346
347 if( preset >= IPC4761_PRESET::CUSTOM )
348 {
349 m_protectionFeatures->SetSelection(
351 }
352 else
353 {
354 m_protectionFeatures->SetSelection( static_cast<int>( preset ) );
355 }
356 }
357 else // check if values are the same for every selected via
358 {
359 if( m_viaX.GetValue() != v->GetPosition().x )
360 m_viaX.SetValue( INDETERMINATE_STATE );
361
362 if( m_viaY.GetValue() != v->GetPosition().y )
363 m_viaY.SetValue( INDETERMINATE_STATE );
364
365 if( m_viaDiameter.GetValue() != v->GetWidth( m_editLayer ) )
367
368 if( m_viaDrill.GetValue() != v->GetDrillValue() )
370
371 if( viaType != v->GetViaType() )
372 viaType = VIATYPE::NOT_DEFINED;
373
374 if( v->GetIsFree() != !m_viaNotFree->GetValue() )
375 m_viaNotFree->Set3StateValue( wxCHK_UNDETERMINED );
376
377 if( selection_first_layer != v->TopLayer() )
378 selection_first_layer = UNDEFINED_LAYER;
379
380 if( selection_last_layer != v->BottomLayer() )
381 selection_last_layer = UNDEFINED_LAYER;
382
383 if( m_annularRingsCtrl->GetSelection() != getAnnularRingSelection( v ) )
384 {
385 if( m_annularRingsCtrl->GetStrings().size() < 4 )
387
388 m_annularRingsCtrl->SetSelection( 3 );
389 }
390
391 if( m_cbTeardrops->GetValue() != v->GetTeardropParams().m_Enabled )
392 m_cbTeardrops->Set3StateValue( wxCHK_UNDETERMINED );
393
395 m_cbTeardropsUseNextTrack->Set3StateValue( wxCHK_UNDETERMINED );
396
397 if( m_teardropMaxLen.GetValue() != v->GetTeardropParams().m_TdMaxLen )
399
400 if( m_teardropMaxWidth.GetValue() != v->GetTeardropParams().m_TdMaxWidth )
402
403 if( m_teardropLenPercent.GetDoubleValue() != v->GetTeardropParams().m_BestLengthRatio *100.0 )
405
406 if( m_teardropWidthPercent.GetDoubleValue() != v->GetTeardropParams().m_BestWidthRatio *100.0 )
408
409 if( m_teardropHDPercent.GetDoubleValue() != v->GetTeardropParams().m_WidthtoSizeFilterRatio*100.0 )
411
412
413 if( static_cast<int>( getViaConfiguration( v ) )
414 != m_protectionFeatures->GetSelection() )
415 {
416 m_protectionFeatures->SetSelection(
418 }
419 }
420
421 if( v->IsLocked() )
422 hasLocked = true;
423 else
424 hasUnlocked = true;
425
426 break;
427 }
428
429 default:
430 {
431 UNIMPLEMENTED_FOR( item->GetClass() );
432 break;
433 }
434 }
435 }
436
437 if( m_tracks )
438 {
439 // Set the track layer selection state:
440 if( track_selection_layer == UNDEFINED_LAYER )
441 {
442 m_TrackLayerCtrl->SetUndefinedLayerName( INDETERMINATE_STATE );
443 m_TrackLayerCtrl->Resync();
444 }
445
446 m_TrackLayerCtrl->SetLayerSelection( track_selection_layer );
447 }
448
449 // Set the vias layers selections state:
450 if( m_vias )
451 {
452 if( selection_first_layer == UNDEFINED_LAYER )
453 {
454 m_ViaStartLayer->SetUndefinedLayerName( INDETERMINATE_STATE );
455 m_ViaStartLayer->Resync();
456 }
457
458 m_ViaStartLayer->SetLayerSelection( selection_first_layer );
459
460 if( selection_last_layer == UNDEFINED_LAYER )
461 {
462 m_ViaEndLayer->SetUndefinedLayerName( INDETERMINATE_STATE );
463 m_ViaEndLayer->Resync();
464 }
465
466 m_ViaEndLayer->SetLayerSelection( selection_last_layer );
467 }
468
469 m_netSelector->SetNetInfo( &m_frame->GetBoard()->GetNetInfo() );
470
471 if ( net >= 0 )
472 {
473 m_netSelector->SetSelectedNetcode( net );
474 }
475 else
476 {
477 m_netSelector->SetIndeterminateString( INDETERMINATE_STATE );
478 m_netSelector->SetIndeterminate();
479 }
480
481 wxASSERT( m_tracks || m_vias );
482
483 if( m_vias )
484 {
485 if( m_viaNotFree->GetValue() && !m_tracks )
486 {
487 // Disable net selector to re-inforce meaning of "Automatically update via nets",
488 // but not when tracks are also selected as then things get harder if you want to
489 // update all the nets to match.
490 m_netSelectorLabel->Disable();
491 m_netSelector->Disable();
492 }
493
494 int viaSelection = wxNOT_FOUND;
495
496 // 0 is the netclass place-holder
497 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
498 {
499 VIA_DIMENSION* viaDimension = &m_frame->GetDesignSettings().m_ViasDimensionsList[ii];
500 wxString msg = m_frame->StringFromValue( viaDimension->m_Diameter )
501 + wxT( " / " )
502 + m_frame->StringFromValue( viaDimension->m_Drill );
503 m_predefinedViaSizesCtrl->Append( msg, viaDimension );
504
505 if( viaSelection == wxNOT_FOUND
506 && m_viaDiameter.GetValue() == viaDimension->m_Diameter
507 && m_viaDrill.GetValue() == viaDimension->m_Drill )
508 {
509 viaSelection = ii - 1;
510 }
511 }
512
513 m_predefinedViaSizesCtrl->SetSelection( viaSelection );
514 m_predefinedViaSizesUnits->SetLabel( EDA_UNIT_UTILS::GetLabel( m_frame->GetUserUnits() ) );
515
516 m_ViaTypeChoice->Enable();
517
518 switch( viaType )
519 {
520 case VIATYPE::THROUGH: m_ViaTypeChoice->SetSelection( 0 ); break;
521 case VIATYPE::MICROVIA: m_ViaTypeChoice->SetSelection( 1 ); break;
522 case VIATYPE::BLIND_BURIED: m_ViaTypeChoice->SetSelection( 2 ); break;
523 case VIATYPE::NOT_DEFINED: m_ViaTypeChoice->SetSelection( wxNOT_FOUND ); break;
524 }
525
526 m_ViaStartLayer->Enable( viaType != VIATYPE::THROUGH );
527 m_ViaEndLayer->Enable( viaType != VIATYPE::THROUGH );
528
529 m_annularRingsLabel->Show( getLayerDepth() > 1 );
530 m_annularRingsCtrl->Show( getLayerDepth() > 1 );
531 m_annularRingsCtrl->Enable( true );
532
534 }
535 else
536 {
537 m_viaNotFree->Hide();
538 m_MainSizer->Hide( m_sbViaSizer, true );
539 }
540
541 if( m_tracks )
542 {
543 int widthSelection = wxNOT_FOUND;
544
545 // 0 is the netclass place-holder
546 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_TrackWidthList.size(); ii++ )
547 {
548 int width = m_frame->GetDesignSettings().m_TrackWidthList[ii];
549 wxString msg = m_frame->StringFromValue( width );
550 m_predefinedTrackWidthsCtrl->Append( msg );
551
552 if( widthSelection == wxNOT_FOUND && m_trackWidth.GetValue() == width )
553 widthSelection = ii - 1;
554 }
555
556 m_predefinedTrackWidthsCtrl->SetSelection( widthSelection );
557 m_predefinedTrackWidthsUnits->SetLabel( EDA_UNIT_UTILS::GetLabel( m_frame->GetUserUnits() ) );
558
559 wxCommandEvent event;
560 onTrackEdit( event );
561 }
562 else
563 {
564 m_MainSizer->Hide( m_sbTrackSizer, true );
565 }
566
567 if( hasLocked && hasUnlocked )
568 m_lockedCbox->Set3StateValue( wxCHK_UNDETERMINED );
569 else if( hasLocked )
570 m_lockedCbox->Set3StateValue( wxCHK_CHECKED );
571 else
572 m_lockedCbox->Set3StateValue( wxCHK_UNCHECKED );
573
574 if( m_tracks )
576 else if( m_netSelector->IsEnabled() )
578 else
580
581 // Now all widgets have the size fixed, call FinishDialogSettings
583
584 return true;
585}
586
587
589{
590 if( m_vias )
591 {
592 int viaSel = m_predefinedViaSizesCtrl->GetSelection();
593
595
596 // 0 is the netclass place-holder
597 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_ViasDimensionsList.size(); ii++ )
598 {
599 VIA_DIMENSION* viaDimension = &m_frame->GetDesignSettings().m_ViasDimensionsList[ii];
600 wxString msg = m_frame->StringFromValue( viaDimension->m_Diameter )
601 + wxT( " / " )
602 + m_frame->StringFromValue( viaDimension->m_Drill );
603 m_predefinedViaSizesCtrl->Append( msg, viaDimension );
604 }
605
606 m_predefinedViaSizesCtrl->SetSelection( viaSel );
607 m_predefinedViaSizesUnits->SetLabel( EDA_UNIT_UTILS::GetLabel( m_frame->GetUserUnits() ) );
608 }
609
610 if( m_tracks )
611 {
612 int trackSel = m_predefinedTrackWidthsCtrl->GetSelection();
613
615
616 // 0 is the netclass place-holder
617 for( unsigned ii = 1; ii < m_frame->GetDesignSettings().m_TrackWidthList.size(); ii++ )
618 {
619 int width = m_frame->GetDesignSettings().m_TrackWidthList[ii];
620 wxString msg = m_frame->StringFromValue( width );
621 m_predefinedTrackWidthsCtrl->Append( msg );
622 }
623
624 m_predefinedTrackWidthsCtrl->SetSelection( trackSel );
625 m_predefinedTrackWidthsUnits->SetLabel( EDA_UNIT_UTILS::GetLabel( m_frame->GetUserUnits() ) );
626 }
627
628 aEvent.Skip();
629}
630
631
632bool DIALOG_TRACK_VIA_PROPERTIES::confirmShortingNets( int aNet, const std::set<int>& shortingNets )
633{
634 wxString msg;
635
636 if( shortingNets.size() == 1 )
637 {
638 msg.Printf( _( "Applying these changes will short net %s with %s." ),
639 m_netSelector->GetValue(),
640 m_frame->GetBoard()->FindNet( *shortingNets.begin() )->GetNetname() );
641 }
642 else
643 {
644 msg.Printf( _( "Applying these changes will short net %s with other nets." ),
645 m_netSelector->GetValue() );
646 }
647
648 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
649 dlg.SetOKCancelLabels( _( "Apply Anyway" ), _( "Cancel Changes" ) );
650 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
651
652 return dlg.ShowModal() == wxID_OK;
653}
654
655
656bool DIALOG_TRACK_VIA_PROPERTIES::confirmPadChange( const std::set<PAD*>& changingPads )
657{
658 wxString msg;
659
660 if( changingPads.size() == 1 )
661 {
662 PAD* pad = *changingPads.begin();
663 msg.Printf( _( "Changing the net will also update %s pad %s to %s." ),
664 pad->GetParentFootprint()->GetReference(),
665 pad->GetNumber(),
666 m_netSelector->GetValue() );
667 }
668 else if( changingPads.size() == 2 )
669 {
670 PAD* pad1 = *changingPads.begin();
671 PAD* pad2 = *( ++changingPads.begin() );
672 msg.Printf( _( "Changing the net will also update %s pad %s and %s pad %s to %s." ),
674 pad1->GetNumber(),
676 pad2->GetNumber(),
677 m_netSelector->GetValue() );
678 }
679 else
680 {
681 msg.Printf( _( "Changing the net will also update %lu connected pads to %s." ),
682 static_cast<unsigned long>( changingPads.size() ),
683 m_netSelector->GetValue() );
684 }
685
686 KIDIALOG dlg( this, msg, _( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
687 dlg.SetOKCancelLabels( _( "Change Nets" ), _( "Leave Nets Unchanged" ) );
688 dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
689
690 return dlg.ShowModal() == wxID_OK;
691}
692
693
695{
696 std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_frame->GetBoard()->GetConnectivity();
697 std::vector<PCB_TRACK*> selected_tracks;
698 std::set<PCB_TRACK*> connected_tracks;
699
700 for( EDA_ITEM* item : m_items )
701 {
702 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( item ) )
703 selected_tracks.push_back( track );
704 }
705
706 for( PCB_TRACK* selected_track : selected_tracks )
707 {
708 for( BOARD_CONNECTED_ITEM* connected_item : connectivity->GetConnectedItems( selected_track ) )
709 {
710 if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( connected_item ) )
711 connected_tracks.insert( track );
712 }
713 }
714
715 // Check for malformed data ONLY; design rules and constraints are the business of DRC.
716
717 if( m_vias )
718 {
719 // TODO: This needs to move into the via class, not the dialog
720
721 if( !m_viaDiameter.Validate( GEOMETRY_MIN_SIZE, INT_MAX )
722 || !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
723 {
724 return false;
725 }
726
727 if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate()
728 && m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate()
729 && m_viaDiameter.GetValue() <= m_viaDrill.GetValue() )
730 {
731 DisplayError( GetParent(), _( "Via hole size must be smaller than via diameter" ) );
732 m_ViaDrillCtrl->SelectAll();
733 m_ViaDrillCtrl->SetFocus();
734 return false;
735 }
736
737 if( m_ViaStartLayer->GetLayerSelection() != UNDEFINED_LAYER &&
738 m_ViaStartLayer->GetLayerSelection() == m_ViaEndLayer->GetLayerSelection() )
739 {
740 DisplayError( GetParent(), _( "Via start layer and end layer cannot be the same" ) );
741 return false;
742 }
743
744 if( !m_viaDiameter.IsIndeterminate() )
745 {
746 int diameter = m_viaDiameter.GetValue();
747 m_viaStack->SetSize( { diameter, diameter }, m_editLayer );
748 }
749 }
750
751 if( m_tracks )
752 {
753 if( !m_trackWidth.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) )
754 return false;
755 }
756
757 // If we survived that, then save the changes:
758 //
759 // We don't bother with updating the nets at this point as it will be useless (any connected
760 // pads will simply drive their existing nets back onto the track segments and vias).
761
762 BOARD_COMMIT commit( m_frame );
763 bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED;
764 bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED;
765
766 for( PCB_TRACK* track : selected_tracks )
767 {
768 commit.Modify( track );
769
770 switch( track->Type() )
771 {
772 case PCB_TRACE_T:
773 case PCB_ARC_T:
774 {
775 wxASSERT( m_tracks );
776
777 if( !m_trackStartX.IsIndeterminate() )
778 track->SetStartX( m_trackStartX.GetIntValue() );
779
780 if( !m_trackStartY.IsIndeterminate() )
781 track->SetStartY( m_trackStartY.GetIntValue() );
782
783 if( !m_trackEndX.IsIndeterminate() )
784 track->SetEndX( m_trackEndX.GetIntValue() );
785
786 if( !m_trackEndY.IsIndeterminate() )
787 track->SetEndY( m_trackEndY.GetIntValue() );
788
789 if( !m_trackWidth.IsIndeterminate() )
790 track->SetWidth( m_trackWidth.GetIntValue() );
791
792 int layer = m_TrackLayerCtrl->GetLayerSelection();
793
794 if( layer != UNDEFINED_LAYER )
795 track->SetLayer( (PCB_LAYER_ID) layer );
796
797 if ( m_trackHasSolderMask->Get3StateValue() != wxCHK_UNDETERMINED )
798 track->SetHasSolderMask( m_trackHasSolderMask->GetValue() );
799
800 if( !m_trackMaskMargin.IsIndeterminate() )
801 {
802 if( m_trackMaskMargin.IsNull() )
803 track->SetLocalSolderMaskMargin( {} );
804 else
805 track->SetLocalSolderMaskMargin( m_trackMaskMargin.GetIntValue() );
806 }
807
808 if( changeLock )
809 track->SetLocked( setLock );
810
811 break;
812 }
813
814 case PCB_VIA_T:
815 {
816 wxASSERT( m_vias );
817 PCB_VIA* via = static_cast<PCB_VIA*>( track );
818
819 if( !m_viaX.IsIndeterminate() )
820 via->SetPosition( VECTOR2I( m_viaX.GetIntValue(), via->GetPosition().y ) );
821
822 if( !m_viaY.IsIndeterminate() )
823 via->SetPosition( VECTOR2I( via->GetPosition().x, m_viaY.GetIntValue() ) );
824
825 if( m_viaNotFree->Get3StateValue() != wxCHK_UNDETERMINED )
826 via->SetIsFree( !m_viaNotFree->GetValue() );
827
828 if( !m_viaDiameter.IsIndeterminate() )
829 via->SetPadstack( *m_viaStack );
830
831 switch( m_ViaTypeChoice->GetSelection() )
832 {
833 case 0: via->SetViaType( VIATYPE::THROUGH ); break;
834 case 1: via->SetViaType( VIATYPE::MICROVIA ); break;
835 case 2: via->SetViaType( VIATYPE::BLIND_BURIED ); break;
836 default: break;
837 }
838
839 PCB_LAYER_ID startLayer = static_cast<PCB_LAYER_ID>( m_ViaStartLayer->GetLayerSelection() );
840 PCB_LAYER_ID endLayer = static_cast<PCB_LAYER_ID>( m_ViaEndLayer->GetLayerSelection() );
841
842 if( startLayer != UNDEFINED_LAYER )
843 {
844 m_viaStack->Drill().start = startLayer;
845 via->SetTopLayer( startLayer );
846 }
847
848 if( endLayer != UNDEFINED_LAYER )
849 {
850 m_viaStack->Drill().end = endLayer;
851 via->SetBottomLayer( endLayer );
852 }
853
854 via->SanitizeLayers();
855
856 switch( m_annularRingsCtrl->GetSelection() )
857 {
858 case 0:
859 via->Padstack().SetUnconnectedLayerMode(
861 break;
862 case 1:
863 via->Padstack().SetUnconnectedLayerMode(
865 break;
866 case 2:
867 via->Padstack().SetUnconnectedLayerMode(
869 break;
870 case 3:
871 via->Padstack().SetUnconnectedLayerMode(
873 break;
874 default:
875 break;
876 }
877
878
879 if( !m_viaDrill.IsIndeterminate() )
880 via->SetDrill( m_viaDrill.GetIntValue() );
881
882 TEARDROP_PARAMETERS* targetParams = &via->GetTeardropParams();
883
884 if( m_cbTeardrops->Get3StateValue() != wxCHK_UNDETERMINED )
885 targetParams->m_Enabled = m_cbTeardrops->GetValue();
886
887 if( m_cbTeardropsUseNextTrack->Get3StateValue() != wxCHK_UNDETERMINED )
888 targetParams->m_AllowUseTwoTracks = m_cbTeardropsUseNextTrack->GetValue();
889
890 if( !m_teardropMaxLen.IsIndeterminate() )
891 targetParams->m_TdMaxLen = m_teardropMaxLen.GetIntValue();
892
893 if( !m_teardropMaxWidth.IsIndeterminate() )
894 targetParams->m_TdMaxWidth = m_teardropMaxWidth.GetIntValue();
895
896 if( !m_teardropLenPercent.IsIndeterminate() )
897 targetParams->m_BestLengthRatio = m_teardropLenPercent.GetDoubleValue() / 100.0;
898
899 if( !m_teardropWidthPercent.IsIndeterminate() )
900 targetParams->m_BestWidthRatio =
901 m_teardropWidthPercent.GetDoubleValue() / 100.0;
902
903 if( !m_teardropHDPercent.IsIndeterminate() )
904 targetParams->m_WidthtoSizeFilterRatio = m_teardropHDPercent.GetDoubleValue() / 100.0;
905
906 if( m_curvedEdges->Get3StateValue() != wxCHK_UNDETERMINED )
907 targetParams->m_CurvedEdges = m_curvedEdges->GetValue();
908
909 if( changeLock )
910 via->SetLocked( setLock );
911
912 auto setSurfaceProtection =
913 [&]( std::optional<bool>& aFront, std::optional<bool>& aBack, IPC4761_SURFACE aProtection )
914 {
915 switch( aProtection )
916 {
918 aFront.reset();
919 aBack.reset();
920 break;
922 aFront = false;
923 aBack = false;
924 break;
926 aFront = true;
927 aBack = false;
928 break;
930 aFront = false;
931 aBack = true;
932 break;
934 aFront = true;
935 aBack = true;
936 break;
937 case IPC4761_SURFACE::CUSTOM: return;
938 }
939 };
940
941 auto setDrillProtection =
942 [&]( std::optional<bool>& aDrill, IPC4761_DRILL aProtection )
943 {
944 switch( aProtection )
945 {
946 case IPC4761_DRILL::FROM_RULES: aDrill.reset(); break;
947 case IPC4761_DRILL::NOT_SET: aDrill = false; break;
948 case IPC4761_DRILL::SET: aDrill = true; break;
949 }
950 };
951
952 IPC4761_PRESET selectedPreset = static_cast<IPC4761_PRESET>( m_protectionFeatures->GetSelection() );
953
954 if( selectedPreset < IPC4761_PRESET::CUSTOM ) // Do not change custom feaure list.
955 {
956 const IPC4761_CONFIGURATION config = m_IPC4761Presets.at( selectedPreset );
957
958 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_solder_mask,
959 via->Padstack().BackOuterLayers().has_solder_mask,
960 config.tent );
961
962 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_plugging,
963 via->Padstack().BackOuterLayers().has_plugging,
964 config.plug );
965
966 setSurfaceProtection( via->Padstack().FrontOuterLayers().has_covering,
967 via->Padstack().BackOuterLayers().has_covering,
968 config.cover );
969
970 setDrillProtection( via->Padstack().Drill().is_filled, config.fill );
971
972 setDrillProtection( via->Padstack().Drill().is_capped, config.cap );
973 }
974
975 break;
976 }
977
978 default:
979 UNIMPLEMENTED_FOR( track->GetClass() );
980 break;
981 }
982 }
983
984 std::set<int> shortingNets;
985 int newNetCode = m_netSelector->GetSelectedNetcode();
986 std::set<PAD*> changingPads;
987
988 // Do NOT use the connectivity code here. It will propagate through zones, and we haven't
989 // refilled those yet so it's going to pick up a whole bunch of other nets any time the track
990 // width was increased.
991 auto collide =
993 {
994 for( PCB_LAYER_ID layer : LSET( a->GetLayerSet() & b->GetLayerSet() ) )
995 {
996 if( a->GetEffectiveShape( layer )->Collide( b->GetEffectiveShape( layer ).get() ) )
997 return true;
998 }
999
1000 return false;
1001 };
1002
1003 for( PCB_TRACK* track : connected_tracks )
1004 {
1005 for( PCB_TRACK* other : m_frame->GetBoard()->Tracks() )
1006 {
1007 if( other->GetNetCode() == track->GetNetCode() || other->GetNetCode() == newNetCode )
1008 continue;
1009
1010 if( collide( track, other ) )
1011 shortingNets.insert( other->GetNetCode() );
1012 }
1013
1014 for( FOOTPRINT* footprint : m_frame->GetBoard()->Footprints() )
1015 {
1016 for( PAD* pad : footprint->Pads() )
1017 {
1018 if( pad->GetNetCode() == newNetCode )
1019 continue;
1020
1021 if( collide( track, pad ) )
1022 {
1023 if( pad->GetNetCode() == track->GetNetCode() )
1024 changingPads.insert( pad );
1025 else
1026 shortingNets.insert( pad->GetNetCode() );
1027 }
1028 }
1029 }
1030 }
1031
1032 if( shortingNets.size() && !confirmShortingNets( newNetCode, shortingNets ) )
1033 {
1034 commit.Revert();
1035 return true;
1036 }
1037
1038 if( !m_netSelector->IsIndeterminate() )
1039 {
1040 if( changingPads.empty() || confirmPadChange( changingPads ) )
1041 {
1042 for( PCB_TRACK* track : selected_tracks )
1043 track->SetNetCode( newNetCode );
1044
1045 for( PAD* pad : changingPads )
1046 {
1047 commit.Modify( pad );
1048 pad->SetNetCode( newNetCode );
1049 }
1050 }
1051 }
1052
1053 commit.Push( _( "Edit Track/Via Properties" ) );
1054 return true;
1055}
1056
1057
1059{
1060 m_viaNotFree->SetValue( false );
1061}
1062
1063
1065{
1066 if( !m_tracks )
1067 {
1068 m_netSelectorLabel->Enable( !m_viaNotFree->GetValue() );
1069 m_netSelector->Enable( !m_viaNotFree->GetValue() );
1070 }
1071}
1072
1073
1075{
1076 m_TrackWidthCtrl->ChangeValue( m_predefinedTrackWidthsCtrl->GetStringSelection() );
1077 m_TrackWidthCtrl->SelectAll();
1078}
1079
1080
1081void DIALOG_TRACK_VIA_PROPERTIES::onWidthEdit( wxCommandEvent& aEvent )
1082{
1083 m_predefinedTrackWidthsCtrl->SetStringSelection( m_TrackWidthCtrl->GetValue() );
1084}
1085
1086
1087void DIALOG_TRACK_VIA_PROPERTIES::onViaSelect( wxCommandEvent& aEvent )
1088{
1089 VIA_DIMENSION* viaDimension = static_cast<VIA_DIMENSION*> ( aEvent.GetClientData() );
1090
1091 m_viaDiameter.ChangeValue( viaDimension->m_Diameter );
1092 m_viaDrill.ChangeValue( viaDimension->m_Drill );
1093}
1094
1095
1097{
1098 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in onPadstackModeChanged" );
1099
1100 switch( m_cbPadstackMode->GetSelection() )
1101 {
1102 default:
1103 case 0: m_viaStack->SetMode( PADSTACK::MODE::NORMAL ); break;
1104 case 1: m_viaStack->SetMode( PADSTACK::MODE::FRONT_INNER_BACK ); break;
1105 case 2: m_viaStack->SetMode( PADSTACK::MODE::CUSTOM ); break;
1106 }
1107
1109}
1110
1111
1113{
1114 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in onEditLayerChanged" );
1115
1116 // Save data from the previous layer
1117 if( !m_viaDiameter.IsIndeterminate() )
1118 {
1119 int diameter = m_viaDiameter.GetValue();
1120 m_viaStack->SetSize( { diameter, diameter }, m_editLayer );
1121 }
1122
1123 switch( m_viaStack->Mode() )
1124 {
1125 default:
1128 break;
1129
1131 switch( m_cbEditLayer->GetSelection() )
1132 {
1133 default:
1134 case 0: m_editLayer = F_Cu; break;
1135 case 1: m_editLayer = PADSTACK::INNER_LAYERS; break;
1136 case 2: m_editLayer = B_Cu; break;
1137 }
1138 break;
1139
1141 {
1142 int layer = m_cbEditLayer->GetSelection();
1143
1144 if( layer < 0 )
1145 layer = 0;
1146
1147 if( m_editLayerCtrlMap.contains( layer ) )
1148 m_editLayer = m_editLayerCtrlMap.at( layer );
1149 else
1150 m_editLayer = F_Cu;
1151 }
1152 }
1153
1154 // Load controls with the current layer
1155 m_viaDiameter.SetValue( m_viaStack->Size( m_editLayer ).x );
1156}
1157
1158
1160{
1161 // NOTE: synchronize changes here with DIALOG_PAD_PROPERTIES::afterPadstackModeChanged
1162
1163 wxCHECK_MSG( m_viaStack, /* void */, "Expected valid via stack in afterPadstackModeChanged" );
1164 m_cbEditLayer->Clear();
1165
1166 BOARD* board = m_frame->GetBoard();
1167
1168 switch( m_viaStack->Mode() )
1169 {
1171 m_cbPadstackMode->SetSelection( 0 );
1172 m_cbEditLayer->Append( _( "All layers" ) );
1173 m_cbEditLayer->Disable();
1176 break;
1177
1179 {
1180 m_cbPadstackMode->SetSelection( 1 );
1181 m_cbEditLayer->Enable();
1182
1183 std::vector choices = {
1184 board->GetLayerName( F_Cu ),
1185 _( "Inner Layers" ),
1186 board->GetLayerName( B_Cu )
1187 };
1188
1189 m_cbEditLayer->Append( choices );
1190
1192 { 0, F_Cu },
1194 { 2, B_Cu }
1195 };
1196
1197 if( m_editLayer != F_Cu && m_editLayer != B_Cu )
1199
1200 break;
1201 }
1202
1204 {
1205 m_cbPadstackMode->SetSelection( 2 );
1206 m_cbEditLayer->Enable();
1207 LSET layers = LSET::AllCuMask() & board->GetEnabledLayers();
1208
1209 for( PCB_LAYER_ID layer : layers.UIOrder() )
1210 {
1211 int idx = m_cbEditLayer->Append( board->GetLayerName( layer ) );
1212 m_editLayerCtrlMap[idx] = layer;
1213 }
1214
1215 break;
1216 }
1217 }
1218
1219 for( const auto& [idx, layer] : m_editLayerCtrlMap )
1220 {
1221 if( layer == m_editLayer )
1222 {
1223 m_cbEditLayer->SetSelection( idx );
1224 break;
1225 }
1226 }
1227}
1228
1229
1231{
1232 int viaType = m_ViaTypeChoice->GetSelection();
1233
1234 if( viaType <= 0 )
1235 return m_frame->GetBoard()->GetCopperLayerCount() - 1;
1236
1237 int startLayer = m_ViaStartLayer->GetLayerSelection();
1238 int endLayer = m_ViaEndLayer->GetLayerSelection();
1239
1240 if( startLayer < 0 || endLayer < 0 )
1241 return m_frame->GetBoard()->GetCopperLayerCount() - 1;
1242 else
1243 return m_frame->GetBoard()->LayerDepth( ToLAYER_ID( startLayer ), ToLAYER_ID( endLayer ) );
1244}
1245
1246
1247void DIALOG_TRACK_VIA_PROPERTIES::onViaEdit( wxCommandEvent& aEvent )
1248{
1249 m_predefinedViaSizesCtrl->SetSelection( wxNOT_FOUND );
1250
1251 if( m_vias )
1252 {
1253 if( m_ViaTypeChoice->GetSelection() != 0 ) // check if selected type isn't through.
1254 {
1255 m_ViaStartLayer->Enable();
1256 m_ViaEndLayer->Enable();
1257 }
1258 else
1259 {
1260 m_ViaStartLayer->SetLayerSelection( F_Cu );
1261 m_ViaEndLayer->SetLayerSelection( B_Cu );
1262
1263 m_ViaStartLayer->Enable( false );
1264 m_ViaEndLayer->Enable( false );
1265 }
1266
1267 m_annularRingsLabel->Show( getLayerDepth() > 1 );
1268 m_annularRingsCtrl->Show( getLayerDepth() > 1 );
1269 m_annularRingsCtrl->Enable( true );
1270 }
1271}
1272
1273
1274void DIALOG_TRACK_VIA_PROPERTIES::onTrackEdit( wxCommandEvent& aEvent )
1275{
1276 bool externalCuLayer = m_TrackLayerCtrl->GetLayerSelection() == F_Cu
1277 || m_TrackLayerCtrl->GetLayerSelection() == B_Cu;
1278
1279 m_techLayersLabel->Enable( externalCuLayer );
1280 m_trackHasSolderMask->Enable( externalCuLayer );
1281
1282 bool showMaskMargin = externalCuLayer && m_trackHasSolderMask->GetValue();
1283
1284 m_trackMaskMarginCtrl->Enable( showMaskMargin );
1285 m_trackMaskMarginLabel->Enable( showMaskMargin );
1286 m_trackMaskMarginUnit->Enable( showMaskMargin );
1287}
1288
1289
1291{
1292 event.Enable( !m_frame->GetBoard()->LegacyTeardrops() );
1293}
1294
const char * name
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()
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition board_item.h:232
bool IsLocked() const override
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.
FOOTPRINT * GetParentFootprint() const
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 wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Definition board.cpp:691
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
Definition board.cpp:923
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:106
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition dialog_shim.h:82
void SetupStandardButtons(std::map< int, wxString > aLabels={})
bool m_useCalculatedSize
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
DIALOG_TRACK_VIA_PROPERTIES_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Track & Via Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU)
void onWidthEdit(wxCommandEvent &aEvent) override
void onUnitsChanged(wxCommandEvent &aEvent)
void onNetSelector(wxCommandEvent &aEvent)
void afterPadstackModeChanged()
Get data from the PCB board and display it to dialog.
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:661
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition kidialog.h:42
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
Definition kidialog.cpp:55
bool SetOKCancelLabels(const ButtonLabel &ok, const ButtonLabel &cancel) override
Definition kidialog.h:52
int ShowModal() override
Definition kidialog.cpp:93
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:726
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
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.
Definition padstack.h:139
@ CUSTOM
Shapes can be defined on arbitrary layers.
Definition padstack.h:141
@ FRONT_INNER_BACK
Up to three shapes can be defined (F_Cu, inner copper layers, B_Cu)
Definition padstack.h:140
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.
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
VECTOR2I GetPosition() const override
Definition pcb_track.h:557
const PADSTACK & Padstack() const
Definition pcb_track.h:459
int GetWidth() const override
PCB_LAYER_ID TopLayer() const
int GetDrillValue() const
Calculate the drill value for vias (m_drill if > 0, or default drill value for the board).
VIATYPE GetViaType() const
Definition pcb_track.h:451
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition shape.h:181
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.
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
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:737
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.
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
KICOMMON_API wxFont GetSmallInfoFont(wxWindow *aWindow)
#define GEOMETRY_MIN_SIZE
Definition pcb_track.h:112
VIATYPE
Definition pcb_track.h:66
@ THROUGH
Definition pcb_track.h:67
@ BLIND_BURIED
Definition pcb_track.h:68
@ NOT_DEFINED
Definition pcb_track.h:71
@ MICROVIA
Definition pcb_track.h:69
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
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695