Better processing of single-empty-row rule for measurements grid.
This commit is contained in:
parent
5fa7be0320
commit
f828d50cb0
|
@ -858,7 +858,7 @@ void SIM_PLOT_FRAME::rebuildSignalsList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// JEY TODO: find and add LET commands
|
// JEY TODO: find and add SPICE "LET" commands
|
||||||
|
|
||||||
// Add user-defined signals
|
// Add user-defined signals
|
||||||
for( int ii = 0; ii < (int) m_userDefinedSignals.size(); ++ii )
|
for( int ii = 0; ii < (int) m_userDefinedSignals.size(); ++ii )
|
||||||
|
@ -1179,14 +1179,45 @@ void SIM_PLOT_FRAME::onMeasurementsGridCellChanged( wxGridEvent& aEvent )
|
||||||
wxFAIL_MSG( wxT( "All other columns are supposed to be read-only!" ) );
|
wxFAIL_MSG( wxT( "All other columns are supposed to be read-only!" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always leave at least one empty row for type-in:
|
// Always leave a single empty row for type-in
|
||||||
row = m_measurementsGrid->GetNumberRows() - 1;
|
|
||||||
|
|
||||||
if( !m_measurementsGrid->GetCellValue( row, COL_MEASUREMENT ).IsEmpty() )
|
int rowCount = (int) m_measurementsGrid->GetNumberRows();
|
||||||
|
int emptyRows = 0;
|
||||||
|
|
||||||
|
for( row = rowCount - 1; row >= 0; row-- )
|
||||||
|
{
|
||||||
|
if( m_measurementsGrid->GetCellValue( row, COL_MEASUREMENT ).IsEmpty() )
|
||||||
|
emptyRows++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( emptyRows > 1 )
|
||||||
|
{
|
||||||
|
int killRows = emptyRows - 1;
|
||||||
|
m_measurementsGrid->DeleteRows( rowCount - killRows, killRows );
|
||||||
|
}
|
||||||
|
else if( emptyRows == 0 )
|
||||||
|
{
|
||||||
m_measurementsGrid->AppendRows( 1 );
|
m_measurementsGrid->AppendRows( 1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user measurement looks something like:
|
||||||
|
* MAX V(out)
|
||||||
|
*
|
||||||
|
* We need to send ngspice a "MEAS" command with the analysis type, an output variable name,
|
||||||
|
* and the signal name. For our example above, this looks something like:
|
||||||
|
* MEAS TRAN meas_result_0 MAX V(out)
|
||||||
|
*
|
||||||
|
* This is also a good time to harvest the signal name prefix so we know what units to show on
|
||||||
|
* the result. For instance, for:
|
||||||
|
* MAX P(out)
|
||||||
|
* we want to show:
|
||||||
|
* 15W
|
||||||
|
*/
|
||||||
void SIM_PLOT_FRAME::UpdateMeasurement( int aRow )
|
void SIM_PLOT_FRAME::UpdateMeasurement( int aRow )
|
||||||
{
|
{
|
||||||
static wxRegEx measureParamsRegEx( wxT( "^"
|
static wxRegEx measureParamsRegEx( wxT( "^"
|
||||||
|
@ -2591,32 +2622,41 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
|
||||||
|
|
||||||
struct TRACE_DESC
|
struct TRACE_DESC
|
||||||
{
|
{
|
||||||
wxString m_name; ///< Name of the measured net/device
|
wxString m_name; ///< Name of the measured net/device
|
||||||
SIM_TRACE_TYPE m_type; ///< Type of the signal
|
SIM_TRACE_TYPE m_type; ///< Type of the signal
|
||||||
|
bool m_current;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<struct TRACE_DESC> traceInfo;
|
std::vector<struct TRACE_DESC> traceInfo;
|
||||||
|
|
||||||
// Get information about all the traces on the plot, remove any no longer in the
|
// Get information about all the traces on the plot; update those that are still in
|
||||||
// signals list, and then update the remainder
|
// the signals list and remove any that aren't
|
||||||
for( const auto& [name, trace] : plotPanel->GetTraces() )
|
for( const auto& [name, trace] : plotPanel->GetTraces() )
|
||||||
{
|
{
|
||||||
struct TRACE_DESC placeholder;
|
struct TRACE_DESC placeholder;
|
||||||
placeholder.m_name = trace->GetName();
|
placeholder.m_name = trace->GetName();
|
||||||
placeholder.m_type = trace->GetType();
|
placeholder.m_type = trace->GetType();
|
||||||
|
placeholder.m_current = false;
|
||||||
|
|
||||||
for( const wxString& signal : m_signals )
|
for( const wxString& signal : m_signals )
|
||||||
{
|
{
|
||||||
if( getTraceName( signal ) == placeholder.m_name )
|
if( getTraceName( signal ) == placeholder.m_name )
|
||||||
{
|
{
|
||||||
traceInfo.push_back( placeholder );
|
placeholder.m_current = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traceInfo.push_back( placeholder );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( const struct TRACE_DESC& trace : traceInfo )
|
for( const struct TRACE_DESC& trace : traceInfo )
|
||||||
updateTrace( trace.m_name, trace.m_type, plotPanel );
|
{
|
||||||
|
if( trace.m_current )
|
||||||
|
updateTrace( trace.m_name, trace.m_type, plotPanel );
|
||||||
|
else
|
||||||
|
removeTrace( trace.m_name );
|
||||||
|
}
|
||||||
|
|
||||||
rebuildSignalsGrid( m_filter->GetValue() );
|
rebuildSignalsGrid( m_filter->GetValue() );
|
||||||
updateSignalsGrid();
|
updateSignalsGrid();
|
||||||
|
|
|
@ -30,6 +30,15 @@
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <wx/valtext.h>
|
#include <wx/valtext.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A SPICE_VALUE_FORMAT holds precision and range info for formatting values.
|
||||||
|
*
|
||||||
|
* The Precision field indicates the number of significant digits to show in the result.
|
||||||
|
*
|
||||||
|
* The range field gives the SI unit prefix for the range or '~' for auto-range, and the
|
||||||
|
* units. For instance "mV" or "~Hz".
|
||||||
|
*/
|
||||||
struct SPICE_VALUE_FORMAT
|
struct SPICE_VALUE_FORMAT
|
||||||
{
|
{
|
||||||
void FromString( const wxString& aString );
|
void FromString( const wxString& aString );
|
||||||
|
|
Loading…
Reference in New Issue