29#include <wx/bmpcbox.h>
32#include <wx/clipbrd.h>
33#include <wx/wupdlock.h>
34#include <wx/richmsgdlg.h>
43#include "magic_enum.hpp"
45#include <wx/textdlg.h>
54#define ID_INCREMENT 256
72static void drawBitmap( wxBitmap& aBitmap, wxColor aColor );
92 == magic_enum::enum_count<DIELECTRIC_MODEL>() );
98 m_panel1->SetBorders(
false,
false,
true,
true );
157 [&]( wxTextCtrl* aTextCtrl )
159 wxString str = aTextCtrl->GetValue();
165 aTextCtrl->ChangeValue( str );
173 convert(
static_cast<wxTextCtrl*
>( ui_item.m_ThicknessCtrl ) );
186 int oldBoardWidth =
static_cast<int>(
m_frame->ValueFromString(
m_tcCTValue->GetValue() ) );
199 std::vector< BOARD_STACKUP_ROW_UI_ITEM* > items_candidate;
203 int min_thickness = 0;
213 wxCheckBox* cb_box =
dynamic_cast<wxCheckBox*
> ( ui_item.m_ThicknessLockCtrl );
215 if( cb_box && !cb_box->GetValue() )
217 items_candidate.push_back( &ui_item );
221 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_ThicknessCtrl );
223 int item_thickness =
m_frame->ValueFromString( textCtrl->GetValue() );
224 min_thickness += item_thickness;
229 if( min_thickness == 0 )
231 title.Printf(
_(
"Enter board thickness in %s:" ),
236 title.Printf(
_(
"Enter expected board thickness (min value %s):" ),
237 m_frame->StringFromValue( min_thickness,
true ) );
240 wxTextEntryDialog dlg(
this, title,
_(
"Adjust Unlocked Dielectric Layers" ) );
242 if( dlg.ShowModal() != wxID_OK )
245 int iu_thickness =
m_frame->ValueFromString( dlg.GetValue() );
247 if( iu_thickness < min_thickness )
249 wxMessageBox( wxString::Format(
_(
"Value too small (min value %s)." ),
250 m_frame->StringFromValue( min_thickness,
true ) ) );
256 if( items_candidate.size() )
259 wxMessageBox(
_(
"All dielectric thickness layers are locked" ) );
270 wxBitmapComboBox* cb =
dynamic_cast<wxBitmapComboBox*
>( item );
274 cb->Disconnect( wxEVT_COMMAND_COMBOBOX_SELECTED,
279 wxButton* matButt =
dynamic_cast<wxButton*
>( item );
283 matButt->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED,
288 wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( item );
292 textCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
302 wxArrayString headers;
303 headers.Add(
_(
"Layers" ) );
306 std::vector<wxArrayString> d_list;
307 std::vector<int> rows;
314 if( !item.m_isEnabled )
321 wxArrayString d_item;
325 d_item.Add( wxString::Format(
_(
"Layer '%s' (sublayer %d/%d)" ),
335 d_list.emplace_back( d_item );
336 rows.push_back( row );
341 headers, d_list, wxEmptyString,
364 wxArrayString headers;
365 headers.Add(
_(
"Layers" ) );
370 std::vector<wxArrayString> d_list;
371 std::vector<int> rows;
378 item->GetSublayersCount() <= 1 )
384 for(
int ii = 0; ii < item->GetSublayersCount(); ii++ )
386 wxArrayString d_item;
388 d_item.Add( wxString::Format(
_(
"Layer '%s' sublayer %d/%d" ),
389 item->FormatDielectricLayerName(),
391 item->GetSublayersCount() ) );
393 d_list.emplace_back( d_item );
394 rows.push_back( row++ );
399 headers, d_list, wxEmptyString,
428 if( item->GetSublayersCount() > 1 )
430 event.Enable(
true );
435 event.Enable(
false );
451 if( wxTheClipboard->Open() )
455 wxTheClipboard->SetData(
new wxTextDataObject( report ) );
456 wxTheClipboard->Flush();
457 wxTheClipboard->Close();
466 const wxBitmapComboBox* choice =
dynamic_cast<wxBitmapComboBox*
>( row.
m_ColorCtrl );
467 int idx = choice ? choice->GetSelection() : 0;
482 const int prePregDefaultThickness =
pcbIUScale.mmToIU( 0.1 );
489 wxASSERT( copperLayerCount % 2 == 0 );
491 int dielectricLayerCount = copperLayerCount - 1;
492 int coreLayerCount = copperLayerCount / 2 - 1;
494 wxASSERT( dielectricLayerCount > 0 );
496 bool currentLayerIsCore =
false;
499 if( copperLayerCount == 2 )
502 currentLayerIsCore =
true;
505 wxASSERT( coreLayerCount > 0 );
507 int prePregLayerCount = dielectricLayerCount - coreLayerCount;
509 int totalWidthOfFixedItems = 0;
518 wxCheckBox* cbLock =
dynamic_cast<wxCheckBox*
>( ui_item.m_ThicknessLockCtrl );
519 wxChoice* layerType =
dynamic_cast<wxChoice*
>( ui_item.m_LayerTypeCtrl );
524 || ( cbLock && cbLock->GetValue() ) )
528 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_ThicknessCtrl );
529 int item_thickness =
m_frame->ValueFromString( textCtrl->GetValue() );
531 totalWidthOfFixedItems += item_thickness;
536 int remainingWidth = targetThickness
537 - totalWidthOfFixedItems
538 - ( prePregDefaultThickness * prePregLayerCount );
540 int prePregThickness = prePregDefaultThickness;
541 int coreThickness = remainingWidth / coreLayerCount;
543 if( coreThickness < prePregThickness )
546 remainingWidth = targetThickness - totalWidthOfFixedItems;
547 prePregThickness = coreThickness = std::max( 0, remainingWidth / dielectricLayerCount );
557 wxChoice* layerType =
dynamic_cast<wxChoice*
>( ui_item.m_LayerTypeCtrl );
565 wxCheckBox* cbLock =
dynamic_cast<wxCheckBox*
>( ui_item.m_ThicknessLockCtrl );
567 if( cbLock && cbLock->GetValue() )
569 currentLayerIsCore = !currentLayerIsCore;
575 int layerThickness = currentLayerIsCore ? coreThickness : prePregThickness;
577 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_ThicknessCtrl );
578 layerType->SetSelection( currentLayerIsCore ? 0 : 1 );
579 textCtrl->SetValue(
m_frame->StringFromValue( layerThickness ) );
581 currentLayerIsCore = !currentLayerIsCore;
597 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_ThicknessCtrl );
598 int item_thickness =
m_frame->ValueFromString( textCtrl->GetValue() );
600 thickness += item_thickness;
603 wxString thicknessStr =
m_frame->StringFromValue( thickness,
true );
623 wxASSERT( copperCount >= 2 );
643 int sub_item = ui_row_item.m_SubItem;
647 wxChoice* choice =
dynamic_cast<wxChoice*
>( ui_row_item.m_LayerTypeCtrl );
655 wxTextCtrl* matName =
dynamic_cast<wxTextCtrl*
>( ui_row_item.m_MaterialCtrl );
660 matName->ChangeValue( item->
GetMaterial( sub_item ) );
668 wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( ui_row_item.m_ThicknessCtrl );
675 wxCheckBox* cb_box =
dynamic_cast<wxCheckBox*
> ( ui_row_item.m_ThicknessLockCtrl );
684 auto bm_combo =
dynamic_cast<wxBitmapComboBox*
>( ui_row_item.m_ColorCtrl );
687 if( item->
GetColor( sub_item ).StartsWith( wxT(
"#" ) ) )
691 ui_row_item.m_UserColor = custom_color;
697 bm_combo->SetString( selected, item->
GetColor( sub_item ) );
700 bm_combo->SetItemBitmap( selected, layerbmp );
721 bm_combo->SetSelection( selected );
727 wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( ui_row_item.m_EpsilonCtrl );
730 textCtrl->ChangeValue( txt );
736 wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( ui_row_item.m_LossTgCtrl );
739 textCtrl->ChangeValue( txt );
748 wxTextCtrl* textCtrl =
dynamic_cast<wxTextCtrl*
>( ui_row_item.m_SpecFreqCtrl );
751 textCtrl->ChangeValue( txt );
753 wxChoice* unitsCtrl =
dynamic_cast<wxChoice*
>( ui_row_item.m_SpecFreqUnitsCtrl );
756 unitsCtrl->SetSelection(
static_cast<int>( units ) );
758 wxChoice* modelCtrl =
dynamic_cast<wxChoice*
>( ui_row_item.m_DielectricModelCtrl );
779 int copperLayersCount = copperMask.count();
795 ui_row_item.m_isEnabled = show_item;
803 if( show_item && !ui_row_item.m_Icon )
806 if( ui_row_item.m_Icon )
809 ui_row_item.m_Icon->Show( show_item );
810 ui_row_item.m_LayerName->Show( show_item );
811 ui_row_item.m_LayerTypeCtrl->Show( show_item );
812 ui_row_item.m_MaterialCtrl->Show( show_item );
814 if( ui_row_item.m_MaterialButt )
815 ui_row_item.m_MaterialButt->Show( show_item );
817 ui_row_item.m_ThicknessCtrl->Show( show_item );
818 ui_row_item.m_ThicknessLockCtrl->Show( show_item );
819 ui_row_item.m_ColorCtrl->Show( show_item );
820 ui_row_item.m_EpsilonCtrl->Show( show_item );
821 ui_row_item.m_LossTgCtrl->Show( show_item );
822 ui_row_item.m_SpecFreqCtrl->Show( show_item );
823 ui_row_item.m_SpecFreqUnitsCtrl->Show( show_item );
824 ui_row_item.m_DielectricModelCtrl->Show( show_item );
832 wxStaticText* emptyText =
new wxStaticText(
m_scGridWin, wxID_ANY, wxEmptyString );
833 m_fgGridSizer->Insert( aPos, emptyText, 0, wxALIGN_CENTER_VERTICAL );
842 int row = ui_row_item.
m_Row;
846 wxStaticBitmap* bitmap =
new wxStaticBitmap(
m_scGridWin, wxID_ANY, wxNullBitmap );
847 m_fgGridSizer->Insert( aPos++, bitmap, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 4 );
848 ui_row_item.
m_Icon = bitmap;
856 lname << wxT(
" (" ) << sublayerIdx +1 << wxT(
"/" )
860 wxStaticText* st_text =
new wxStaticText(
m_scGridWin, wxID_ANY, lname );
861 m_fgGridSizer->Insert( aPos++, st_text, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
866 if( sublayerIdx == 0 )
868 wxChoice* choice =
new wxChoice(
m_scGridWin, wxID_ANY, wxDefaultPosition, wxDefaultSize,
871 m_fgGridSizer->Insert( aPos++, choice, 1, wxEXPAND|wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
884 m_fgGridSizer->Insert( aPos++, st_text, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 1 );
885 st_text->Show(
true );
891 lname =
_(
"Copper" );
895 st_text =
new wxStaticText(
m_scGridWin, wxID_ANY, lname );
896 m_fgGridSizer->Insert( aPos++, st_text, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
902 wxString matName = item->
GetMaterial( sublayerIdx );
904 wxBoxSizer* bSizerMat =
new wxBoxSizer( wxHORIZONTAL );
905 m_fgGridSizer->Insert( aPos++, bSizerMat, 1, wxRIGHT|wxEXPAND, 4 );
906 wxTextCtrl* textCtrl =
new wxTextCtrl(
m_scGridWin, wxID_ANY );
909 textCtrl->ChangeValue( matName );
914 bSizerMat->Add( textCtrl, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
917 wxDefaultSize, wxBU_EXACTFIT );
918 bSizerMat->Add( m_buttonMat, 0, wxALIGN_CENTER_VERTICAL, 2 );
920 m_buttonMat->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
938 textCtrl->ChangeValue(
m_frame->StringFromValue( item->
GetThickness( sublayerIdx ),
true ) );
939 m_fgGridSizer->Insert( aPos++, textCtrl, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
941 textCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED,
951 m_fgGridSizer->Insert( aPos++, cb_box, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_CENTER_HORIZONTAL, 2 );
968 if( item->
GetColor( sublayerIdx ).StartsWith( wxT(
"#" ) ) )
978 m_fgGridSizer->Insert( aPos++, bm_combo, 1, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL|wxEXPAND, 2 );
980 if( item->
GetColor( sublayerIdx ).StartsWith( wxT(
"#" ) ) )
983 bm_combo->SetString( selected, item->
GetColor( sublayerIdx ) );
998 bm_combo->SetSelection( selected );
1009 wxTextCtrl* textCtrl =
new wxTextCtrl(
m_scGridWin, wxID_ANY, wxEmptyString, wxDefaultPosition,
1011 textCtrl->ChangeValue( txt );
1012 m_fgGridSizer->Insert( aPos++, textCtrl, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
1023 wxTextCtrl* textCtrl =
new wxTextCtrl(
m_scGridWin, wxID_ANY, wxEmptyString, wxDefaultPosition,
1025 textCtrl->ChangeValue( txt );
1026 m_fgGridSizer->Insert( aPos++, textCtrl, 0, wxLEFT|wxRIGHT|wxALIGN_CENTER_VERTICAL, 2 );
1036 const double freq = item->
GetSpecFreq( sublayerIdx );
1041 wxTextCtrl* textCtrl =
new wxTextCtrl(
m_scGridWin, wxID_ANY, wxEmptyString, wxDefaultPosition,
1043 textCtrl->ChangeValue( txt );
1044 m_fgGridSizer->Insert( aPos++, textCtrl, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 2 );
1049 m_fgGridSizer->Insert( aPos++, unitsCtrl, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 2 );
1051 unitsCtrl->SetSelection(
static_cast<int>( units ) );
1055 m_fgGridSizer->Insert( aPos++, modelCtrl, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_VERTICAL, 2 );
1057 modelCtrl->SetSelection(
static_cast<int>( item->
GetDielectricModel( sublayerIdx ) ) );
1084 if( ui_item.m_MaterialCtrl )
1085 ui_item.m_MaterialCtrl->SetSizer(
nullptr );
1088 delete ui_item.m_Icon;
1089 delete ui_item.m_LayerName;
1090 delete ui_item.m_LayerTypeCtrl;
1091 delete ui_item.m_MaterialCtrl;
1092 delete ui_item.m_MaterialButt;
1093 delete ui_item.m_ThicknessCtrl;
1094 delete ui_item.m_ThicknessLockCtrl;
1095 delete ui_item.m_ColorCtrl;
1096 delete ui_item.m_EpsilonCtrl;
1097 delete ui_item.m_LossTgCtrl;
1098 delete ui_item.m_SpecFreqCtrl;
1099 delete ui_item.m_SpecFreqUnitsCtrl;
1100 delete ui_item.m_DielectricModelCtrl;
1112 m_fgGridSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
1117 const int sizer_flags = wxALIGN_CENTER_VERTICAL | wxALL | wxALIGN_CENTER_HORIZONTAL;
1149 if( aCreateInitialStackup || aRelinkStackup )
1151 if( aCreateInitialStackup )
1170 if( item->GetBrdLayerId() == board_item->GetBrdLayerId() )
1172 *item = *board_item;
1182 if( item->GetDielectricLayerId() == board_item->GetDielectricLayerId() )
1184 *item = *board_item;
1196 for(
int sub_idx = 0; sub_idx < item->GetSublayersCount(); sub_idx++ )
1209 bool success =
true;
1215 if( !ui_item.m_isEnabled )
1219 int sub_item = ui_item.m_SubItem;
1230 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_EpsilonCtrl );
1231 wxString txt = textCtrl->GetValue();
1233 if( txt.ToDouble( &value ) && value >= 0.0 )
1235 else if( txt.ToCDouble( &value ) && value >= 0.0 )
1240 error_msg <<
_(
"Incorrect value for Epsilon R (Epsilon R must be positive or null if not used)" );
1246 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_LossTgCtrl );
1247 wxString txt = textCtrl->GetValue();
1249 if( txt.ToDouble( &value ) && value >= 0.0 )
1253 else if( txt.ToCDouble( &value ) && value >= 0.0 )
1261 if( !error_msg.IsEmpty() )
1262 error_msg << wxT(
"\n" );
1264 error_msg <<
_(
"Incorrect value for Loss tg (Loss tg must be positive or null if not used)" );
1270 wxChoice* modelCtrl =
static_cast<wxChoice*
>( ui_item.m_DielectricModelCtrl );
1271 int modelIdx = modelCtrl->GetCurrentSelection();
1274 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_SpecFreqCtrl );
1275 wxString txt = textCtrl->GetValue();
1277 wxChoice* unitsCtrl =
static_cast<wxChoice*
>( ui_item.m_SpecFreqUnitsCtrl );
1278 int unitsIdx = unitsCtrl->GetCurrentSelection();
1280 auto setFreqValue = [unitsIdx, item, sub_item](
const double freq )
1284 case 3: item->SetSpecFreq( freq * 1e9, sub_item );
break;
1285 case 2: item->SetSpecFreq( freq * 1e6, sub_item );
break;
1286 case 1: item->SetSpecFreq( freq * 1e3, sub_item );
break;
1287 default: item->SetSpecFreq( freq );
break;
1291 if( txt.ToDouble( &value ) && value >= 0.0 )
1293 setFreqValue( value );
1295 else if( txt.ToCDouble( &value ) && value >= 0.0 )
1297 setFreqValue( value );
1303 if( !error_msg.IsEmpty() )
1304 error_msg << wxT(
"\n" );
1306 error_msg <<
_(
"Incorrect value for specified frequency (must be positive or null if not used)" );
1312 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_MaterialCtrl );
1313 item->
SetMaterial( textCtrl->GetValue(), sub_item );
1324 wxChoice* choice =
dynamic_cast<wxChoice*
>( ui_item.m_LayerTypeCtrl );
1328 int idx = choice->GetSelection();
1339 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>( ui_item.m_ThicknessCtrl );
1340 int new_thickness =
m_frame->ValueFromString( textCtrl->GetValue() );
1344 if( new_thickness < 0 )
1348 if( !error_msg.IsEmpty() )
1349 error_msg << wxT(
"\n" );
1351 error_msg <<
_(
"A layer thickness is < 0. Fix it" );
1357 wxCheckBox* cb_box =
static_cast<wxCheckBox*
>( ui_item.m_ThicknessLockCtrl );
1364 wxBitmapComboBox* choice =
dynamic_cast<wxBitmapComboBox*
>( ui_item.m_ColorCtrl );
1368 int idx = choice->GetSelection();
1371 item->
SetColor( ui_item.m_UserColor.ToHexString(), sub_item );
1380 wxMessageBox( error_msg,
_(
"Errors" ) );
1412 if( item->IsEnabled() )
1444 m_frame->GetBoard()->BumpDrillModelGeneration();
1499 int idx =
event.GetSelection();
1500 int item_id =
event.GetId();
1517 wxBitmapComboBox* combo =
static_cast<wxBitmapComboBox*
>( FindWindowById( item_id ) );
1526 combo->SetItemBitmap( combo->GetCount() - 1, layerbmp );
1528 combo->SetSelection( idx );
1556 for(
int ii = 0; ii < item->GetSublayersCount(); ii++ )
1559 item->GetEpsilonR( ii ),
1560 item->GetLossTangent( ii ) );
1562 if( idx < 0 && !item->GetMaterial().IsEmpty() )
1566 new_mat.
m_Name = item->GetMaterial( ii );
1567 new_mat.
m_EpsilonR = item->GetEpsilonR( ii );
1584 default: item_mat_list =
nullptr;
break;
1587 wxCHECK( item_mat_list, );
1596 if( substrate.
m_Name.IsEmpty() )
1604 wxTextCtrl* textCtrl =
static_cast<wxTextCtrl*
>(
m_rowUiItemsList[row].m_MaterialCtrl );
1605 textCtrl->ChangeValue( item->
GetMaterial( sub_item ) );
1608 && !item->
GetColor( sub_item ).StartsWith(
"#" ) )
1610 if( substrate.
m_Name.IsSameAs(
"PTFE" )
1611 || substrate.
m_Name.IsSameAs(
"Teflon" ) )
1613 item->
SetColor(
"PTFE natural", sub_item );
1615 else if( substrate.
m_Name.IsSameAs(
"Polyimide" )
1616 || substrate.
m_Name.IsSameAs(
"Kapton" ) )
1618 item->
SetColor(
"Polyimide", sub_item );
1620 else if( substrate.
m_Name.IsSameAs(
"Al" ) )
1622 item->
SetColor(
"Aluminum", sub_item );
1626 item->
SetColor(
"FR4 natural", sub_item );
1630 wxBitmapComboBox* picker =
static_cast<wxBitmapComboBox*
>(
m_rowUiItemsList[row].m_ColorCtrl );
1636 picker->SetSelection( ii );
1644 textCtrl =
dynamic_cast<wxTextCtrl*
>(
m_rowUiItemsList[row].m_EpsilonCtrl );
1653 textCtrl =
dynamic_cast<wxTextCtrl*
>(
m_rowUiItemsList[row].m_LossTgCtrl );
1664 wxString value =
event.GetString();
1691 wxASSERT( st_item );
1707 wxFAIL_MSG( wxT(
"PANEL_SETUP_BOARD_STACKUP::getColorIconItem: unrecognized item type" ) );
1711 wxASSERT_MSG( color.IsOk(), wxT(
"Invalid color in PCB stackup" ) );
1720 const int bitmap_depth = 24;
1728 st_bitmap->SetBitmap( bmp );
1747 wxDefaultPosition, wxDefaultSize, 0,
nullptr, wxCB_READONLY );
1761 && aStackupItem->
GetColor().StartsWith( wxT(
"#" ) ) )
1764 curr_color =
COLOR4D( label );
1775 combo->Append( label, layerbmp );
1783 int sel = combo->GetSelection();
1784 combo->SetSelection( combo->GetCount() - 1 );
1786 combo->SetMinSize( wxSize( -1, -1 ) );
1787 wxSize bestSize = combo->GetBestSize();
1790 combo->SetMinSize( bestSize );
1791 combo->SetSelection( sel );
1797 combo->Connect( wxEVT_COMMAND_COMBOBOX_SELECTED,
1801 combo->Bind( wxEVT_COMBOBOX_DROPDOWN,
1802 [combo]( wxCommandEvent& aEvent )
1804 combo->SetString( combo->GetCount() - 1,
_(
"Custom..." ) );
1813 wxNativePixelData data( aBitmap );
1814 wxNativePixelData::Iterator p( data );
1816 for(
int yy = 0; yy < data.GetHeight(); yy++ )
1818 wxNativePixelData::Iterator rowStart = p;
1820 for(
int xx = 0; xx < data.GetWidth(); xx++ )
1822 p.Red() = aColor.Red();
1823 p.Green() = aColor.Green();
1824 p.Blue() = aColor.Blue();
1829 p.OffsetY( data, 1 );
constexpr EDA_IU_SCALE pcbIUScale
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
bool IsPrmSpecified(const wxString &aPrmValue)
@ BS_ITEM_TYPE_SILKSCREEN
@ BS_ITEM_TYPE_DIELECTRIC
@ BS_ITEM_TYPE_SOLDERPASTE
@ BS_ITEM_TYPE_SOLDERMASK
wxString BuildStackupReport(BOARD_STACKUP &aStackup, EDA_UNITS aUnits)
Container for design settings for a BOARD object.
Manage one layer needed to make a physical board.
void AddDielectricPrms(int aDielectricPrmsIdx)
Add (insert) a DIELECTRIC_PRMS item to m_DielectricPrmsList all values are set to default.
wxString GetTypeName() const
DIELECTRIC_MODEL GetDielectricModel(int aDielectricSubLayer=0) const
int GetSublayersCount() const
bool HasSpecFreqValue() const
double GetEpsilonR(int aDielectricSubLayer=0) const
wxString GetColor(int aDielectricSubLayer=0) const
bool HasEpsilonRValue() const
void SetThickness(int aThickness, int aDielectricSubLayer=0)
bool IsMaterialEditable() const
void SetDielectricModel(DIELECTRIC_MODEL aModel, int aDielectricSubLayer=0)
void SetThicknessLocked(bool aLocked, int aDielectricSubLayer=0)
wxString FormatDielectricLayerName() const
wxString GetLayerName() const
void SetMaterial(const wxString &aName, int aDielectricSubLayer=0)
bool HasLossTangentValue() const
PCB_LAYER_ID GetBrdLayerId() const
bool IsThicknessEditable() const
void SetLossTangent(double aTg, int aDielectricSubLayer=0)
int GetThickness(int aDielectricSubLayer=0) const
void SetEnabled(bool aEnable)
BOARD_STACKUP_ITEM_TYPE GetType() const
wxString GetMaterial(int aDielectricSubLayer=0) const
void SetTypeName(const wxString &aName)
bool IsThicknessLocked(int aDielectricSubLayer=0) const
wxString FormatEpsilonR(int aDielectricSubLayer=0) const
void SetColor(const wxString &aColorName, int aDielectricSubLayer=0)
void SetEpsilonR(double aEpsilon, int aDielectricSubLayer=0)
void SetLayerName(const wxString &aName)
double GetSpecFreq(int aDielectricSubLayer=0) const
void RemoveDielectricPrms(int aDielectricPrmsIdx)
Remove a DIELECTRIC_PRMS item from m_DielectricPrmsList.
int GetDielectricLayerId() const
bool IsColorEditable() const
wxString FormatLossTangent(int aDielectricSubLayer=0) const
double GetLossTangent(int aDielectricSubLayer=0) const
Manage layers needed to make a physical board.
void RemoveAll()
Delete all items in list and clear the list.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
static LSET StackupAllowedBrdLayers()
int BuildBoardThicknessFromStackup() const
bool m_HasDielectricConstrains
True if some layers have impedance controlled tracks or have specific constrains for micro-wave appli...
void Add(BOARD_STACKUP_ITEM *aItem)
Add a new item in stackup layer.
void FormatBoardStackup(OUTPUTFORMATTER *aFormatter, const BOARD *aBoard) const
Write the stackup info on board file.
Information pertinent to a Pcbnew printed circuit board.
BOARD_DESIGN_SETTINGS & GetDesignSettings()
KIGFX::COLOR4D GetColor()
a Dialog to select/change/add a dielectric material from a material list
DIELECTRIC_SUBSTRATE GetSelectedSubstrate()
int AppendSubstrate(DIELECTRIC_SUBSTRATE &aItem)
Append a item in list similar to aItem.
int FindSubstrate(DIELECTRIC_SUBSTRATE *aItem)
Find a item in list similar to aItem.
void SetListLabel(const wxString &aLabel)
A color representation with 4 components: red, green, blue, alpha.
wxString ToHexString() const
wxColour ToColour() const
static void DrawColorSwatch(wxBitmap &aLayerbmp, const COLOR4D &aBackground, const COLOR4D &aColor)
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
LSET is a set of PCB_LAYER_IDs.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static const LSET & ExternalCuMask()
Return a mask holding the Front and Bottom layers.
static const LSET & InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
static PAGED_DIALOG * GetDialog(wxWindow *aWindow)
wxScrolledWindow * m_scGridWin
wxStaticText * m_staticTextLayer
wxStaticText * m_staticTextMaterial
wxStaticText * m_staticTextLayerId
wxStaticText * m_staticTextSpecFreq
wxStaticBitmap * m_bitmapLockThickness
wxStaticText * m_staticTextColor
wxCheckBox * m_impedanceControlled
wxStaticText * m_staticTextType
wxStaticText * m_staticTextThickness
wxFlexGridSizer * m_fgGridSizer
wxStaticText * m_staticTextDielectricModel
wxStaticText * m_staticTextLossTg
PANEL_SETUP_BOARD_STACKUP_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
wxStaticText * m_staticTextSpecFreqUnits
wxStaticText * m_staticTextEpsilonR
wxChoice * m_choiceCopperLayers
int GetSublayerId(int aRow)
static wxString m_dielecticModelChoices[2]
The choices available for dielectric frequency-dependency model.
void onAddDielectricLayer(wxCommandEvent &event) override
DIELECTRIC_SUBSTRATE_LIST m_silkscreenMatList
wxArrayString m_core_prepreg_choice
void onExportToClipboard(wxCommandEvent &event) override
bool transferDataFromUIToStackup()
Transfer current UI settings to m_stackup but not to the board.
PANEL_SETUP_BOARD_STACKUP(wxWindow *aParentWindow, PCB_EDIT_FRAME *aFrame, PANEL_SETUP_LAYERS *aPanelLayers, PANEL_SETUP_BOARD_FINISH *aPanelFinish)
wxSize m_numericTextCtrlSize
std::vector< wxControl * > m_controlItemsList
void onColorSelected(wxCommandEvent &event)
bool TransferDataFromWindow() override
void onCopperLayersSelCount(wxCommandEvent &event) override
void onUnitsChanged(wxCommandEvent &event)
void ImportSettingsFrom(BOARD *aBoard)
wxColor getColorIconItem(int aRow)
PANEL_SETUP_BOARD_FINISH * m_panelFinish
void updateIconColor(int aRow=-1)
Update the icons color (swatches in first grid column)
static std::pair< double, FREQ_UNITS > normaliseFrequency(double aFreq)
Normalise a frequency in Hz to a value and a units multiplier.
void updateCopperLayerCount()
Updates the enabled copper layers when the dropdown is changed.
wxColor GetSelectedColor(int aRow) const
Return the color currently selected for the row aRow.
void onRemoveDielectricLayer(wxCommandEvent &event) override
wxControl * addSpacer(int aPos)
add a Spacer in m_fgGridSizer when a empty cell is needed
int computeBoardThickness()
Recompute the board thickness and update the textbox.
void setDefaultLayerWidths(int targetThickness)
Set the widths of dielectric layers to sensible defaults.
static wxString m_specFreqChoices[4]
The choices available for spec freq units.
void synchronizeWithBoard(bool aFullSync)
Synchronize the full stackup shown in m_fgGridSizer according to the stackup of the current board and...
void buildLayerStackPanel(bool aCreateInitialStackup=false, bool aRelinkStackup=false)
Populate m_fgGridSizer with items to handle stackup parameters This is a full list: all copper layers...
void onThicknessChange(wxCommandEvent &event)
BOARD_DESIGN_SETTINGS * m_brdSettings
int GetCopperLayerCount() const
BOARD_STACKUP_ITEM * GetStackupItem(int aRow)
void showOnlyActiveLayers()
Show or do not show items in m_fgGridSizer according to the stackup of the current board.
DIELECTRIC_SUBSTRATE_LIST m_solderMaskMatList
std::vector< BOARD_STACKUP_ROW_UI_ITEM > m_rowUiItemsList
PANEL_SETUP_LAYERS * m_panelLayers
void onRemoveDielUI(wxUpdateUIEvent &event) override
void lazyBuildRowUI(BOARD_STACKUP_ROW_UI_ITEM &ui_row_item, int aPos)
Create the controls in a BOARD_STACKUP_ROW_UI_ITEM relative to the aStackupItem.
DIELECTRIC_SUBSTRATE_LIST m_delectricMatList
wxBitmapComboBox * createColorBox(BOARD_STACKUP_ITEM *aStackupItem, int aRow)
creates a bitmap combobox to select a layer color
wxSize m_numericFieldsSize
void disconnectEvents()
disconnect event handlers connected to wxControl items found in list m_controlItemsList
void onAdjustDielectricThickness(wxCommandEvent &event) override
void OnLayersOptionsChanged(const LSET &aNewLayerSet)
Must be called if the copper layers count has changed or solder mask, solder paste or silkscreen laye...
~PANEL_SETUP_BOARD_STACKUP()
void onMaterialChange(wxCommandEvent &event)
wxSize m_colorSwatchesSize
void rebuildLayerStackPanel(bool aRelinkItems=false)
Populate m_fgGridSizer with items to handle stackup parameters If previous items are in list,...
The main frame for Pcbnew.
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API long long int ValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue in aUnits to internal units used by the application.
KICOMMON_API wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Return the string from aValue according to aUnits (inch, mm ...) for display.
KICOMMON_API wxString GetText(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
static wxColor pasteColor(200, 200, 200)
static wxColor copperColor(220, 180, 30)
static wxColor dielectricColor(75, 120, 75)
static void drawBitmap(wxBitmap &aBitmap, wxColor aColor)
@ ID_ITEM_THICKNESS_LOCKED
std::vector< FAB_LAYER_COLOR > dummy
const std::vector< FAB_LAYER_COLOR > & GetStandardColors(BOARD_STACKUP_ITEM_TYPE aType)
int GetColorUserDefinedListIdx(BOARD_STACKUP_ITEM_TYPE aType)
bool IsCustomColorIdx(BOARD_STACKUP_ITEM_TYPE aType, int aIdx)
KIGFX::COLOR4D GetStandardColor(BOARD_STACKUP_ITEM_TYPE aType, int aIdx)
wxString NotSpecifiedPrm()
const wxString & GetStandardColorName(BOARD_STACKUP_ITEM_TYPE aType, int aIdx)
KIGFX::COLOR4D GetDefaultUserColor(BOARD_STACKUP_ITEM_TYPE aType)
std::string UIDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 We want to avoid scientific ...
wxControl * m_ThicknessCtrl
wxControl * m_SpecFreqUnitsCtrl
wxStaticText * m_LayerName
wxControl * m_ThicknessLockCtrl
wxControl * m_EpsilonCtrl
wxButton * m_MaterialButt
wxControl * m_SpecFreqCtrl
wxControl * m_MaterialCtrl
wxControl * m_DielectricModelCtrl
wxControl * m_LayerTypeCtrl
BOARD_STACKUP_ITEM * m_Item
DIELECTRIC_MODEL
Frequency-domain model used for the substrate dielectric properties.