diff --git a/pcb_calculator/CMakeLists.txt b/pcb_calculator/CMakeLists.txt
index 826ff13495..99b0f78f9e 100644
--- a/pcb_calculator/CMakeLists.txt
+++ b/pcb_calculator/CMakeLists.txt
@@ -36,6 +36,8 @@ set( PCB_CALCULATOR_SRCS
calculator_panels/panel_transline_base.cpp
calculator_panels/panel_via_size.cpp
calculator_panels/panel_via_size_base.cpp
+ calculator_panels/panel_wavelength.cpp
+ calculator_panels/panel_wavelength_base.cpp
transline_ident.cpp
widgets/unit_selector.cpp
transline/transline.cpp
@@ -50,6 +52,7 @@ set( PCB_CALCULATOR_SRCS
attenuators/attenuator_classes.cpp
dialogs/dialog_regulator_form_base.cpp
dialogs/dialog_regulator_form.cpp
+ pcb_calculator_utils.cpp
../common/env_vars.cpp # needed on MSW to avoid a link issue (a symbol not found)
)
diff --git a/pcb_calculator/calculator_panels/panel_wavelength.cpp b/pcb_calculator/calculator_panels/panel_wavelength.cpp
new file mode 100644
index 0000000000..0f200edad8
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_wavelength.cpp
@@ -0,0 +1,258 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2022 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "pcb_calculator_utils.h"
+#include "common_data.h"
+
+#define SPEED_LIGHT 299792458
+
+PANEL_WAVELENGTH::PANEL_WAVELENGTH( wxWindow* parent, wxWindowID id, const wxPoint& pos,
+ const wxSize& size, long style, const wxString& name ) :
+ PANEL_WAVELENGTH_BASE( parent, id, pos, size, style, name )
+{
+}
+
+void PANEL_WAVELENGTH::SaveSettings( PCB_CALCULATOR_SETTINGS* aCfg )
+{
+ aCfg->m_wavelength.frequency = m_frequency;
+ aCfg->m_wavelength.permittivity = m_permittivity;
+ aCfg->m_wavelength.permeability = m_permeability;
+
+ aCfg->m_wavelength.frequencyUnit = m_frequencyUnit->GetSelection();
+ aCfg->m_wavelength.periodUnit = m_periodUnit->GetSelection();
+ aCfg->m_wavelength.wavelengthVacuumUnit = m_wavelengthVacuumUnit->GetSelection();
+ aCfg->m_wavelength.wavelengthMediumUnit = m_wavelengthMediumUnit->GetSelection();
+ aCfg->m_wavelength.speedUnit = m_speedUnit->GetSelection();
+}
+
+
+void PANEL_WAVELENGTH::LoadSettings( PCB_CALCULATOR_SETTINGS* aCfg )
+{
+ m_frequencyUnit->SetSelection( aCfg->m_wavelength.frequencyUnit );
+ m_periodUnit->SetSelection( aCfg->m_wavelength.periodUnit );
+ m_wavelengthVacuumUnit->SetSelection( aCfg->m_wavelength.wavelengthVacuumUnit );
+ m_wavelengthMediumUnit->SetSelection( aCfg->m_wavelength.wavelengthMediumUnit );
+ m_speedUnit->SetSelection( aCfg->m_wavelength.speedUnit );
+
+ m_permittivity = aCfg->m_wavelength.permittivity;
+ m_permeability = aCfg->m_wavelength.permeability;
+ m_frequency = aCfg->m_wavelength.frequency;
+
+ wxString value;
+ value = wxString( "" ) << m_permittivity;
+ m_permittivityCtrl->SetValue( value );
+ value = wxString( "" ) << m_permeability;
+ m_permeabilityCtrl->SetValue( value );
+
+ update( m_frequency );
+}
+
+void PANEL_WAVELENGTH::updateUnits( wxCommandEvent& aEvent )
+{
+ update( m_frequency );
+}
+
+
+void PANEL_WAVELENGTH::update( double aFrequency )
+{
+ m_updatingUI = true;
+ wxString value;
+
+ if( !m_updatingFrequency )
+ {
+ value = wxString( "" ) << aFrequency / m_frequencyUnit->GetUnitScale();
+ m_frequencyCtrl->SetValue( value );
+ }
+
+ if( !m_updatingPeriod )
+ {
+ value = wxString( "" ) << 1 / aFrequency / m_periodUnit->GetUnitScale();
+ m_periodCtrl->SetValue( value );
+ }
+
+ if( !m_updatingWavelengthVacuum )
+ {
+ value = wxString( "" ) << SPEED_LIGHT / aFrequency / m_wavelengthVacuumUnit->GetUnitScale();
+ m_wavelengthVacuumCtrl->SetValue( value );
+ }
+
+ if( !m_updatingWavelengthMedium )
+ {
+ value = wxString( "" ) << SPEED_LIGHT / aFrequency / sqrt( m_permittivity * m_permeability )
+ / m_wavelengthMediumUnit->GetUnitScale();
+ m_wavelengthMediumCtrl->SetValue( value );
+ }
+
+ if( !m_updatingSpeed )
+ {
+ value = wxString( "" ) << SPEED_LIGHT / sqrt( m_permittivity * m_permeability )
+ / m_speedUnit->GetUnitScale();
+ m_speedCtrl->SetValue( value );
+ }
+
+ m_frequency = aFrequency;
+
+ m_updatingFrequency = false;
+ m_updatingPeriod = false;
+ m_updatingWavelengthVacuum = false;
+ m_updatingWavelengthMedium = false;
+ m_updatingSpeed = false;
+
+ m_updatingUI = false;
+}
+
+void PANEL_WAVELENGTH::OnFrequencyChange( wxCommandEvent& event )
+{
+ double value;
+
+ if( m_updatingUI )
+ {
+ return;
+ }
+
+ wxString input = m_frequencyCtrl->GetValue();
+
+ if( input.ToDouble( &value ) )
+ {
+ if( value > 0 )
+ {
+ m_updatingFrequency = true;
+ update( value * m_frequencyUnit->GetUnitScale() );
+ }
+ }
+}
+
+void PANEL_WAVELENGTH::OnPeriodChange( wxCommandEvent& event )
+{
+ double value;
+
+ if( m_updatingUI )
+ {
+ return;
+ }
+
+ wxString input = m_periodCtrl->GetValue();
+
+ if( input.ToDouble( &value ) )
+ {
+ if( value > 0 )
+ {
+ m_updatingPeriod = true;
+ update( 1 / ( value * m_periodUnit->GetUnitScale() ) );
+ }
+ }
+}
+
+void PANEL_WAVELENGTH::OnWavelengthVacuumChange( wxCommandEvent& event )
+{
+ if( m_updatingUI )
+ {
+ return;
+ }
+
+ double value;
+ wxString input = m_wavelengthVacuumCtrl->GetValue();
+
+ if( input.ToDouble( &value ) )
+ {
+ if( value > 0 )
+ {
+ value *= m_wavelengthVacuumUnit->GetUnitScale();
+ m_updatingWavelengthVacuum = true;
+ update( SPEED_LIGHT / value );
+ }
+ }
+};
+
+
+void PANEL_WAVELENGTH::OnWavelengthMediumChange( wxCommandEvent& event )
+{
+ if( m_updatingUI )
+ {
+ return;
+ }
+
+ double value;
+ wxString input = m_wavelengthMediumCtrl->GetValue();
+
+ if( input.ToDouble( &value ) )
+ {
+ if( value > 0 )
+ {
+ value *= m_wavelengthMediumUnit->GetUnitScale();
+ m_updatingWavelengthMedium = true;
+ update( SPEED_LIGHT / value / sqrt( m_permittivity * m_permeability ) );
+ }
+ }
+};
+
+void PANEL_WAVELENGTH::OnPermittivityChange( wxCommandEvent& event )
+{
+ double value;
+ wxString input = m_permittivityCtrl->GetValue();
+
+ if( input.ToDouble( &value ) )
+ {
+ if( value >= 1 )
+ {
+ m_permittivity = value;
+ update( m_frequency );
+ }
+ }
+}
+
+void PANEL_WAVELENGTH::OnPermeabilityChange( wxCommandEvent& event )
+{
+ double value;
+ wxString input = m_permeabilityCtrl->GetValue();
+
+ if( input.ToDouble( &value ) )
+ {
+ if( value >= 1 )
+ {
+ m_permeability = value;
+ update( m_frequency );
+ }
+ }
+}
+
+void PANEL_WAVELENGTH::OnButtonPermittivity( wxCommandEvent& event )
+{
+ wxArrayString list = StandardRelativeDielectricConstantList();
+ list.Add( "" ); // Add an empty line for no selection
+
+ // Find the previous choice index:
+ wxString prevChoiceStr = m_permittivityCtrl->GetValue();
+ int prevChoice = 0;
+ findMatch( list, prevChoiceStr, prevChoice );
+
+ int index = wxGetSingleChoiceIndex( wxEmptyString, _( "Relative Dielectric Constants" ), list,
+ prevChoice );
+
+ if( index >= 0 && !list.Item( index ).IsEmpty() )
+ {
+ m_permittivityCtrl->SetValue( list.Item( index ).BeforeFirst( ' ' ) );
+ // wx automatically calls onPermittivity()
+ }
+}
diff --git a/pcb_calculator/calculator_panels/panel_wavelength.h b/pcb_calculator/calculator_panels/panel_wavelength.h
new file mode 100644
index 0000000000..0b7e32590e
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_wavelength.h
@@ -0,0 +1,65 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2022 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#ifndef PANEL_WAVELENGTH_H
+#define PANEL_WAVELENGTH_H
+
+#include "panel_wavelength_base.h"
+
+class PCB_CALCULATOR_SETTINGS;
+
+class PANEL_WAVELENGTH : public PANEL_WAVELENGTH_BASE
+{
+public:
+ PANEL_WAVELENGTH( wxWindow* parent, wxWindowID id = wxID_ANY,
+ const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+ long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
+ ~PANEL_WAVELENGTH(){};
+
+ // Methods from CALCULATOR_PANEL that must be overriden
+ void LoadSettings( PCB_CALCULATOR_SETTINGS* aCfg ) override;
+ void SaveSettings( PCB_CALCULATOR_SETTINGS* aCfg ) override;
+ void ThemeChanged() override{};
+
+ void OnFrequencyChange( wxCommandEvent& event );
+ void OnPeriodChange( wxCommandEvent& event );
+ void OnWavelengthVacuumChange( wxCommandEvent& event );
+ void OnWavelengthMediumChange( wxCommandEvent& event );
+ void OnPermittivityChange( wxCommandEvent& event );
+ void OnPermeabilityChange( wxCommandEvent& event );
+ void OnButtonPermittivity( wxCommandEvent& event );
+
+private:
+ void update( double aFrequency );
+ void updateUnits( wxCommandEvent& aEvent );
+
+ double m_permittivity = 1;
+ double m_permeability = 1;
+ double m_frequency = 1;
+
+ bool m_updatingFrequency = false;
+ bool m_updatingPeriod = false;
+ bool m_updatingWavelengthVacuum = false;
+ bool m_updatingWavelengthMedium = false;
+ bool m_updatingSpeed = false;
+
+ bool m_updatingUI = false;
+};
+
+#endif
diff --git a/pcb_calculator/calculator_panels/panel_wavelength_base.cpp b/pcb_calculator/calculator_panels/panel_wavelength_base.cpp
new file mode 100644
index 0000000000..b298685787
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_wavelength_base.cpp
@@ -0,0 +1,151 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version 3.10.1)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "widgets/unit_selector.h"
+
+#include "panel_wavelength_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+PANEL_WAVELENGTH_BASE::PANEL_WAVELENGTH_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : CALCULATOR_PANEL( parent, id, pos, size, style, name )
+{
+ wxBoxSizer* bSizer6;
+ bSizer6 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizer4;
+ bSizer4 = new wxBoxSizer( wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer3;
+ fgSizer3 = new wxFlexGridSizer( 0, 3, 0, 0 );
+ fgSizer3->SetFlexibleDirection( wxBOTH );
+ fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_staticText18 = new wxStaticText( this, wxID_ANY, _("Frequency:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText18->Wrap( -1 );
+ fgSizer3->Add( m_staticText18, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_frequencyCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_frequencyCtrl, 0, wxALL|wxEXPAND, 5 );
+
+ wxArrayString m_frequencyUnitChoices;
+ m_frequencyUnit = new UNIT_SELECTOR_FREQUENCY( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_frequencyUnitChoices, 0 );
+ m_frequencyUnit->SetSelection( 0 );
+ fgSizer3->Add( m_frequencyUnit, 0, wxALL, 5 );
+
+ m_staticText181 = new wxStaticText( this, wxID_ANY, _("Period:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText181->Wrap( -1 );
+ fgSizer3->Add( m_staticText181, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_periodCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_periodCtrl, 0, wxALL, 5 );
+
+ wxArrayString m_periodUnitChoices;
+ m_periodUnit = new UNIT_SELECTOR_TIME( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_periodUnitChoices, 0 );
+ m_periodUnit->SetSelection( 0 );
+ fgSizer3->Add( m_periodUnit, 0, wxALL, 5 );
+
+ m_staticText1811 = new wxStaticText( this, wxID_ANY, _("Wavelength in vacuum:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText1811->Wrap( -1 );
+ fgSizer3->Add( m_staticText1811, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_wavelengthVacuumCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_wavelengthVacuumCtrl, 0, wxALL, 5 );
+
+ wxArrayString m_wavelengthVacuumUnitChoices;
+ m_wavelengthVacuumUnit = new UNIT_SELECTOR_LEN_CABLE( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_wavelengthVacuumUnitChoices, 0 );
+ m_wavelengthVacuumUnit->SetSelection( 0 );
+ fgSizer3->Add( m_wavelengthVacuumUnit, 0, wxALL, 5 );
+
+ m_staticText18111 = new wxStaticText( this, wxID_ANY, _("Wavelength in medium:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText18111->Wrap( -1 );
+ fgSizer3->Add( m_staticText18111, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_wavelengthMediumCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_wavelengthMediumCtrl, 0, wxALL, 5 );
+
+ wxArrayString m_wavelengthMediumUnitChoices;
+ m_wavelengthMediumUnit = new UNIT_SELECTOR_LEN_CABLE( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_wavelengthMediumUnitChoices, 0 );
+ m_wavelengthMediumUnit->SetSelection( 0 );
+ fgSizer3->Add( m_wavelengthMediumUnit, 0, wxALL, 5 );
+
+ m_staticText181112 = new wxStaticText( this, wxID_ANY, _("Speed in medium:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText181112->Wrap( -1 );
+ fgSizer3->Add( m_staticText181112, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_speedCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_speedCtrl->Enable( false );
+
+ fgSizer3->Add( m_speedCtrl, 0, wxALL, 5 );
+
+ wxArrayString m_speedUnitChoices;
+ m_speedUnit = new UNIT_SELECTOR_SPEED( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_speedUnitChoices, 0 );
+ m_speedUnit->SetSelection( 0 );
+ fgSizer3->Add( m_speedUnit, 0, wxALL, 5 );
+
+ m_staticText181111 = new wxStaticText( this, wxID_ANY, _("er:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText181111->Wrap( -1 );
+ m_staticText181111->SetToolTip( _("relative permittivity (dielectric constant)") );
+
+ fgSizer3->Add( m_staticText181111, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_permittivityCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_permittivityCtrl, 0, wxALL, 5 );
+
+ m_button1 = new wxButton( this, wxID_ANY, _("..."), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_button1, 0, wxALL, 5 );
+
+ m_staticText42 = new wxStaticText( this, wxID_ANY, _("mur:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_staticText42->Wrap( -1 );
+ m_staticText42->SetToolTip( _("relative permeability") );
+
+ fgSizer3->Add( m_staticText42, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_permeabilityCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer3->Add( m_permeabilityCtrl, 0, wxALL, 5 );
+
+
+ bSizer4->Add( fgSizer3, 1, wxEXPAND, 5 );
+
+
+ bSizer6->Add( bSizer4, 1, wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizer6 );
+ this->Layout();
+
+ // Connect Events
+ m_frequencyCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnFrequencyChange ), NULL, this );
+ m_frequencyUnit->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_periodCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnPeriodChange ), NULL, this );
+ m_periodUnit->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_wavelengthVacuumCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnWavelengthVacuumChange ), NULL, this );
+ m_wavelengthVacuumUnit->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_wavelengthMediumCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnWavelengthMediumChange ), NULL, this );
+ m_wavelengthMediumUnit->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_speedUnit->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_permittivityCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnPermittivityChange ), NULL, this );
+ m_button1->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnButtonPermittivity ), NULL, this );
+ m_permeabilityCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnPermeabilityChange ), NULL, this );
+}
+
+PANEL_WAVELENGTH_BASE::~PANEL_WAVELENGTH_BASE()
+{
+ // Disconnect Events
+ m_frequencyCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnFrequencyChange ), NULL, this );
+ m_frequencyUnit->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_periodCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnPeriodChange ), NULL, this );
+ m_periodUnit->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_wavelengthVacuumCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnWavelengthVacuumChange ), NULL, this );
+ m_wavelengthVacuumUnit->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_wavelengthMediumCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnWavelengthMediumChange ), NULL, this );
+ m_wavelengthMediumUnit->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_speedUnit->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::updateUnits ), NULL, this );
+ m_permittivityCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnPermittivityChange ), NULL, this );
+ m_button1->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnButtonPermittivity ), NULL, this );
+ m_permeabilityCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_WAVELENGTH_BASE::OnPermeabilityChange ), NULL, this );
+
+}
diff --git a/pcb_calculator/calculator_panels/panel_wavelength_base.fbp b/pcb_calculator/calculator_panels/panel_wavelength_base.fbp
new file mode 100644
index 0000000000..e12a117ac3
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_wavelength_base.fbp
@@ -0,0 +1,1372 @@
+
+
+
+
+
diff --git a/pcb_calculator/calculator_panels/panel_wavelength_base.h b/pcb_calculator/calculator_panels/panel_wavelength_base.h
new file mode 100644
index 0000000000..4d3770b5bb
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_wavelength_base.h
@@ -0,0 +1,84 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version 3.10.1)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include
+#include
+#include
+class UNIT_SELECTOR_FREQUENCY;
+class UNIT_SELECTOR_LEN_CABLE;
+class UNIT_SELECTOR_SPEED;
+class UNIT_SELECTOR_TIME;
+
+#include "calculator_panels/calculator_panel.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class PANEL_WAVELENGTH_BASE
+///////////////////////////////////////////////////////////////////////////////
+class PANEL_WAVELENGTH_BASE : public CALCULATOR_PANEL
+{
+ private:
+
+ protected:
+ wxStaticText* m_staticText18;
+ wxTextCtrl* m_frequencyCtrl;
+ UNIT_SELECTOR_FREQUENCY* m_frequencyUnit;
+ wxStaticText* m_staticText181;
+ wxTextCtrl* m_periodCtrl;
+ UNIT_SELECTOR_TIME* m_periodUnit;
+ wxStaticText* m_staticText1811;
+ wxTextCtrl* m_wavelengthVacuumCtrl;
+ UNIT_SELECTOR_LEN_CABLE* m_wavelengthVacuumUnit;
+ wxStaticText* m_staticText18111;
+ wxTextCtrl* m_wavelengthMediumCtrl;
+ UNIT_SELECTOR_LEN_CABLE* m_wavelengthMediumUnit;
+ wxStaticText* m_staticText181112;
+ wxTextCtrl* m_speedCtrl;
+ UNIT_SELECTOR_SPEED* m_speedUnit;
+ wxStaticText* m_staticText181111;
+ wxTextCtrl* m_permittivityCtrl;
+ wxButton* m_button1;
+ wxStaticText* m_staticText42;
+ wxTextCtrl* m_permeabilityCtrl;
+
+ // Virtual event handlers, override them in your derived class
+ virtual void OnFrequencyChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void updateUnits( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPeriodChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnWavelengthVacuumChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnWavelengthMediumChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPermittivityChange( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnButtonPermittivity( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnPermeabilityChange( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ PANEL_WAVELENGTH_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 736,453 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
+
+ ~PANEL_WAVELENGTH_BASE();
+
+};
+
diff --git a/pcb_calculator/pcb_calculator_frame.cpp b/pcb_calculator/pcb_calculator_frame.cpp
index d83a4a86bc..36706eb3f1 100644
--- a/pcb_calculator/pcb_calculator_frame.cpp
+++ b/pcb_calculator/pcb_calculator_frame.cpp
@@ -44,6 +44,7 @@
#include
#include
#include
+#include
PCB_CALCULATOR_FRAME::PCB_CALCULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
@@ -97,7 +98,9 @@ PCB_CALCULATOR_FRAME::PCB_CALCULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_treebook->AddPage( nullptr, _( "High speed" ) );
-
+ AddCalculator( new PANEL_WAVELENGTH( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ wxTAB_TRAVERSAL ),
+ _( "Wavelength" ) );
AddCalculator( new PANEL_ATTENUATORS( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
_( "RF Attenuators" ) );
AddCalculator( new PANEL_TRANSLINE( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
diff --git a/pcb_calculator/pcb_calculator_settings.cpp b/pcb_calculator/pcb_calculator_settings.cpp
index db096d7a3b..577703a9e8 100644
--- a/pcb_calculator/pcb_calculator_settings.cpp
+++ b/pcb_calculator/pcb_calculator_settings.cpp
@@ -36,7 +36,7 @@ const int pcbCalculatorSchemaVersion = 0;
PCB_CALCULATOR_SETTINGS::PCB_CALCULATOR_SETTINGS() :
APP_SETTINGS_BASE( "pcb_calculator", pcbCalculatorSchemaVersion ), m_Attenuators(),
m_BoardClassUnits( 0 ), m_ColorCodeTolerance( 0 ), m_Electrical(), m_LastPage( 0 ),
- m_Regulators(), m_cableSize(), m_TrackWidth(), m_TransLine(), m_ViaSize()
+ m_Regulators(), m_cableSize(), m_wavelength(), m_TrackWidth(), m_TransLine(), m_ViaSize()
{
// Build settings:
m_params.emplace_back( new PARAM( "board_class_units", &m_BoardClassUnits, 0 ) );
@@ -97,6 +97,28 @@ PCB_CALCULATOR_SETTINGS::PCB_CALCULATOR_SETTINGS() :
m_params.emplace_back( new PARAM( "cable_size.lengthUnit", &m_cableSize.lengthUnit, 0 ) );
+ m_params.emplace_back(
+ new PARAM( "wavelength.frequency", &m_wavelength.frequency, 1e9 ) );
+
+ m_params.emplace_back(
+ new PARAM( "wavelength.permeability", &m_wavelength.permeability, 1 ) );
+
+ m_params.emplace_back(
+ new PARAM( "wavelength.permittivity", &m_wavelength.permittivity, 4.6 ) );
+
+ m_params.emplace_back(
+ new PARAM( "wavelength.frequencyUnit", &m_wavelength.frequencyUnit, 0 ) );
+
+ m_params.emplace_back( new PARAM( "wavelength.periodUnit", &m_wavelength.periodUnit, 0 ) );
+
+ m_params.emplace_back( new PARAM( "wavelength.wavelengthVacuumUnit",
+ &m_wavelength.wavelengthVacuumUnit, 0 ) );
+
+ m_params.emplace_back( new PARAM( "wavelength.wavelengthMediumUnit",
+ &m_wavelength.wavelengthMediumUnit, 0 ) );
+
+ m_params.emplace_back( new PARAM( "wavelength.speedUnit", &m_wavelength.speedUnit, 0 ) );
+
m_params.emplace_back( new PARAM( "track_width.current",
&m_TrackWidth.current, "1.0" ) );
diff --git a/pcb_calculator/pcb_calculator_settings.h b/pcb_calculator/pcb_calculator_settings.h
index 06309a3874..789a238928 100644
--- a/pcb_calculator/pcb_calculator_settings.h
+++ b/pcb_calculator/pcb_calculator_settings.h
@@ -70,6 +70,18 @@ public:
int lengthUnit;
};
+ struct WAVELENGTH
+ {
+ double permittivity;
+ double permeability;
+ double frequency;
+ int frequencyUnit;
+ int periodUnit;
+ int wavelengthVacuumUnit;
+ int wavelengthMediumUnit;
+ int speedUnit;
+ };
+
struct TRACK_WIDTH
{
wxString current;
@@ -149,6 +161,8 @@ public:
CABLE_SIZE m_cableSize;
+ WAVELENGTH m_wavelength;
+
TRACK_WIDTH m_TrackWidth;
TRANSMISSION_LINE m_TransLine;
diff --git a/pcb_calculator/pcb_calculator_utils.cpp b/pcb_calculator/pcb_calculator_utils.cpp
new file mode 100644
index 0000000000..c129f09dee
--- /dev/null
+++ b/pcb_calculator/pcb_calculator_utils.cpp
@@ -0,0 +1,92 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2022 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include
+
+bool findMatch( wxArrayString& aList, const wxString& aValue, int& aIdx )
+{
+ bool success = false;
+ // Find the previous choice index:
+ aIdx = 0;
+
+ // Some countries use comma instead of point as separator.
+ // The value can be enter with pint or comma
+ // use point for string comparisons:
+ wxString cvalue = aValue;
+ cvalue.Replace( ',', '.' );
+
+ // First compare strings:
+ for( wxString& text : aList )
+ {
+ if( text.IsEmpty() ) // No match found: select the empty line choice
+ break;
+
+ wxString val_str = text.BeforeFirst( ' ' );
+ val_str.Replace( ',', '.' );
+
+ // compare string values
+ if( val_str == cvalue )
+ {
+ success = true;
+ break;
+ }
+
+ aIdx++;
+ }
+
+ // Due to multiple ways to write a double, if string values
+ // do not match, compare double values
+ if( !success )
+ {
+ struct lconv* lc = localeconv();
+ char localeDecimalSeparator = *lc->decimal_point;
+
+ if( localeDecimalSeparator == ',' )
+ cvalue.Replace( '.', ',' );
+
+ double curr_value;
+ cvalue.ToDouble( &curr_value );
+
+ aIdx = 0;
+
+ for( wxString& text : aList )
+ {
+ if( text.IsEmpty() ) // No match found: select the empty line choice
+ break;
+
+ double val;
+ wxString val_str = text.BeforeFirst( ' ' );
+
+ if( localeDecimalSeparator == ',' )
+ val_str.Replace( '.', ',' );
+
+ val_str.ToDouble( &val );;
+
+ if( curr_value == val )
+ {
+ success = true;
+ break;
+ }
+
+ aIdx++;
+ }
+ }
+
+ return success;
+}
diff --git a/pcb_calculator/pcb_calculator_utils.h b/pcb_calculator/pcb_calculator_utils.h
new file mode 100644
index 0000000000..5a4e68ac58
--- /dev/null
+++ b/pcb_calculator/pcb_calculator_utils.h
@@ -0,0 +1,32 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2022 Kicad Developers, see AUTHORS.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+
+#include
+#include
+
+#ifndef PCB_CALCULATOR_UTILS_H
+#define PCB_CALCULATOR_UTILS_H
+// Display a selection of usual Er, TanD, Rho values
+// List format is
+
+// A helper function to find the choice in a list of values
+// return true if a index in aList that matches aValue is found.
+bool findMatch( wxArrayString& aList, const wxString& aValue, int& aIdx );
+
+#endif
\ No newline at end of file
diff --git a/pcb_calculator/transline_dlg_funct.cpp b/pcb_calculator/transline_dlg_funct.cpp
index c03fb71856..5f712c0cf0 100644
--- a/pcb_calculator/transline_dlg_funct.cpp
+++ b/pcb_calculator/transline_dlg_funct.cpp
@@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2011 jean-pierre.charras
- * Copyright (C) 1992-2021 Kicad Developers, see AUTHORS.txt for contributors.
+ * Copyright (C) 1992-2022 Kicad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -25,90 +25,11 @@
#include
#include
#include
+#include
extern double DoubleFromString( const wxString& TextValue );
-
-// Display a selection of usual Er, TanD, Rho values
-// List format is
-
-
-// A helper function to find the choice in a list of values
-// return true if a index in aList that matches aValue is found.
-static bool findMatch( wxArrayString& aList, const wxString& aValue, int& aIdx )
-{
- bool success = false;
- // Find the previous choice index:
- aIdx = 0;
-
- // Some countries use comma instead of point as separator.
- // The value can be enter with pint or comma
- // use point for string comparisons:
- wxString cvalue = aValue;
- cvalue.Replace( ',', '.' );
-
- // First compare strings:
- for( wxString& text: aList )
- {
- if( text.IsEmpty() ) // No match found: select the empty line choice
- break;
-
- wxString val_str = text.BeforeFirst( ' ' );
- val_str.Replace( ',', '.' );
-
- // compare string values
- if( val_str == cvalue )
- {
- success = true;
- break;
- }
-
- aIdx++;
- }
-
- // Due to multiple ways to write a double, if string values
- // do not match, compare double values
- if( !success )
- {
- struct lconv* lc = localeconv();
- char localeDecimalSeparator = *lc->decimal_point;
-
- if( localeDecimalSeparator == ',' )
- cvalue.Replace( '.', ',' );
-
- double curr_value;
- cvalue.ToDouble( &curr_value );
-
- aIdx = 0;
-
- for( wxString& text: aList )
- {
- if( text.IsEmpty() ) // No match found: select the empty line choice
- break;
-
- double val;
- wxString val_str = text.BeforeFirst( ' ' );
-
- if( localeDecimalSeparator == ',' )
- val_str.Replace( '.', ',' );
-
- val_str.ToDouble( &val );;
-
- if( curr_value == val )
- {
- success = true;
- break;
- }
-
- aIdx++;
- }
- }
-
- return success;
-}
-
-
void PANEL_TRANSLINE::OnTranslineEpsilonR_Button( wxCommandEvent& event )
{
wxArrayString list = StandardRelativeDielectricConstantList();
diff --git a/pcb_calculator/units_scales.h b/pcb_calculator/units_scales.h
index 9341f4aaa4..cab10792dd 100644
--- a/pcb_calculator/units_scales.h
+++ b/pcb_calculator/units_scales.h
@@ -53,4 +53,15 @@
#define UNIT_OHM_PER_FEET 3.28084 // Ohm per feet to Ohm per meter
#define UNIT_OHM_PER_1000FEET 3280.84 // Ohm per feet to Ohm per meter
+#define UNIT_METER_PER_SECOND 1.0 // meter per second to meter per second
+#define UNIT_KILOMETER_PER_HOUR ( 1 / 3.6 ) // km/h to m/s
+#define UNIT_FEET_PER_SECOND 0.3048 // ft/s to m/s
+#define UNIT_MILES_PER_HOUR 1609.34 // mi/h to m/s
+
+#define UNIT_SECOND 1.0 // second to second
+#define UNIT_MSECOND 1e-3 // millisecond to second
+#define UNIT_USECOND 1e-6 // microsecond to second
+#define UNIT_NSECOND 1e-9 // nanosecond to second
+#define UNIT_PSECOND 1e-12 // picosecond to second
+
#endif // UNITS_SCALES_H
diff --git a/pcb_calculator/widgets/unit_selector.cpp b/pcb_calculator/widgets/unit_selector.cpp
index 4e23cf454c..32cd41f63b 100644
--- a/pcb_calculator/widgets/unit_selector.cpp
+++ b/pcb_calculator/widgets/unit_selector.cpp
@@ -231,4 +231,56 @@ double UNIT_SELECTOR_LEN_CABLE::GetUnitScale()
case 4: return UNIT_FEET; break;
}
return 1.0;
+}
+
+UNIT_SELECTOR_SPEED::UNIT_SELECTOR_SPEED( wxWindow* parent, wxWindowID id, const wxPoint& pos,
+ const wxSize& size, const wxArrayString& choices,
+ long style ) :
+ UNIT_SELECTOR( parent, id, pos, size, choices, style )
+{
+ Append( _( "m/s" ) );
+ Append( _( "ft/s" ) );
+ Append( _( "km/h" ) );
+ Append( _( "mi/h" ) );
+}
+
+/*
+ * Function GetUnitScale
+ * return the scaling factor to convert users units
+ * to normalized units (meter per second)
+ */
+double UNIT_SELECTOR_SPEED::GetUnitScale()
+{
+ switch( GetCurrentSelection() )
+ {
+ case 0: return UNIT_METER_PER_SECOND; break;
+ case 1: return UNIT_FEET_PER_SECOND; break;
+ case 2: return UNIT_KILOMETER_PER_HOUR; break;
+ case 3: return UNIT_MILES_PER_HOUR; break;
+ }
+ return 1.0;
+}
+
+UNIT_SELECTOR_TIME::UNIT_SELECTOR_TIME( wxWindow* parent, wxWindowID id, const wxPoint& pos,
+ const wxSize& size, const wxArrayString& choices,
+ long style ) :
+ UNIT_SELECTOR( parent, id, pos, size, choices, style )
+{
+ Append( _( "ns" ) );
+ Append( _( "ps" ) );
+}
+
+/*
+ * Function GetUnitScale
+ * return the scaling factor to convert users units
+ * to normalized units (second)
+ */
+double UNIT_SELECTOR_TIME::GetUnitScale()
+{
+ switch( GetCurrentSelection() )
+ {
+ case 0: return UNIT_NSECOND; break;
+ case 1: return UNIT_PSECOND; break;
+ }
+ return 1.0;
}
\ No newline at end of file
diff --git a/pcb_calculator/widgets/unit_selector.h b/pcb_calculator/widgets/unit_selector.h
index 1fcd711b98..27e1e0de62 100644
--- a/pcb_calculator/widgets/unit_selector.h
+++ b/pcb_calculator/widgets/unit_selector.h
@@ -159,5 +159,33 @@ public:
double GetUnitScale() override;
};
+class UNIT_SELECTOR_SPEED : public UNIT_SELECTOR
+{
+public:
+ UNIT_SELECTOR_SPEED( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
+ const wxArrayString& choices, long style = 0 );
+
+ /**
+ * Function GetUnitScale
+ * @return the scaling factor to convert users units
+ * to normalized units ( ohm/m )
+ */
+ double GetUnitScale() override;
+};
+
+class UNIT_SELECTOR_TIME : public UNIT_SELECTOR
+{
+public:
+ UNIT_SELECTOR_TIME( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
+ const wxArrayString& choices, long style = 0 );
+
+ /**
+ * Function GetUnitScale
+ * @return the scaling factor to convert users units
+ * to normalized units ( ohm/m )
+ */
+ double GetUnitScale() override;
+};
+
#endif // UNIT_SELECTOR_H