From 5bded609ebd25e774da43f898502ce7231af087b Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Mon, 13 May 2019 16:31:28 -0500 Subject: [PATCH] Add postprocessing support to channels Minor fixes to math trace handling Postprocessing settings are not yet saved --- clients/tde/src/part/scope/layout.ui | 5 + clients/tde/src/part/scope/part.cpp | 156 +++++++++++++++++++++++- clients/tde/src/part/scope/part.h | 42 ++++++- clients/tde/src/widgets/tracewidget.cpp | 32 ++++- clients/tde/src/widgets/tracewidget.h | 11 +- 5 files changed, 229 insertions(+), 17 deletions(-) diff --git a/clients/tde/src/part/scope/layout.ui b/clients/tde/src/part/scope/layout.ui index 5447780..e14cb65 100644 --- a/clients/tde/src/part/scope/layout.ui +++ b/clients/tde/src/part/scope/layout.ui @@ -123,6 +123,11 @@ + + postProcessTraceControlLayoutWidget + + + mathTraceControlLayoutWidget diff --git a/clients/tde/src/part/scope/part.cpp b/clients/tde/src/part/scope/part.cpp index 44dbb84..e5ebfa4 100644 --- a/clients/tde/src/part/scope/part.cpp +++ b/clients/tde/src/part/scope/part.cpp @@ -15,9 +15,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (c) 2012-2019 Timothy Pearson - * Raptor Engineering - * http://www.raptorengineeringinc.com + * (c) 2012 - 2019 Timothy Pearson + * Raptor Engineering, LLC + * http://www.raptorengineering.com */ #include "define.h" @@ -191,6 +191,63 @@ void TraceControlWidget::triggerRequested() { emit(triggerChannelChangeRequested()); } +TracePostProcessControlWidget::TracePostProcessControlWidget(TQWidget *parent, const char *name) + : TQWidget(parent, name) +{ + TQGridLayout *topGrid = new TQGridLayout(this); + m_groupBox = new TQGroupBox(this); + m_groupBox->setColumnLayout(0, TQt::Vertical); + topGrid->addMultiCellWidget(m_groupBox, 0, 0, 0, 0); + m_groupBox->setTitle(i18n("Unknown Channel")); + m_primaryLayout = new TQGridLayout(m_groupBox->layout(), 1, 1, KDialog::spacingHint()); + + m_postProcessEnabledCheckBox = new TQCheckBox(m_groupBox); + connect(m_postProcessEnabledCheckBox, SIGNAL(clicked()), this, SLOT(enableClicked())); + m_postProcessEnabledCheckBox->setText(i18n("Enable")); + m_primaryLayout->addMultiCellWidget(m_postProcessEnabledCheckBox, 0, 0, 0, 0); + + m_voltsMultiplierSpinBox = new FloatSpinBox(m_groupBox); + m_voltsMultiplierSpinBox->setFloatMax(1000); + m_voltsMultiplierSpinBox->setFloatMin(-1000); + m_voltsMultiplierSpinBox->setFloatValue(1.0); + connect(m_voltsMultiplierSpinBox, SIGNAL(floatValueChanged(double)), this, SLOT(vMultChanged(double))); + m_voltsMultiplierSpinBox->setEnabled(false); + m_primaryLayout->addMultiCellWidget(m_voltsMultiplierSpinBox, 0, 0, 1, 1); + + TQLabel* label = new TQLabel(m_groupBox); + label->setText(i18n("V/div multiplier")); + m_primaryLayout->addMultiCellWidget(label, 0, 0, 2, 2); +} + +TracePostProcessControlWidget::~TracePostProcessControlWidget() { + // +} + +void TracePostProcessControlWidget::setSelectedVoltsMultiplier(double vmult) { + m_voltsMultiplierSpinBox->setFloatValue(vmult); +} + +void TracePostProcessControlWidget::setPostProcessEnabled(bool enabled) { + m_postProcessEnabledCheckBox->setChecked(enabled); + m_voltsMultiplierSpinBox->setEnabled(enabled); +} + +void TracePostProcessControlWidget::setTraceName(TQString name) { + m_groupBox->setTitle(name); +} + +void TracePostProcessControlWidget::enableClicked() { + bool enabled = m_postProcessEnabledCheckBox->isOn(); + m_voltsMultiplierSpinBox->setEnabled(enabled); + emit(enableChanged(enabled)); +} + +void TracePostProcessControlWidget::vMultChanged(double vmult) { + Q_UNUSED(vmult) + double value = m_voltsMultiplierSpinBox->floatValue(); + emit(voltsMultiplierChanged(value)); +} + MathTraceControlWidget::MathTraceControlWidget(TQWidget *parent, const char *name) : TQWidget(parent, name) { @@ -494,7 +551,10 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject * m_traceAllowedVoltsDiv[traceno].clear(); m_voltsDiv[traceno] = 0; m_secsDiv[traceno] = 0; + m_channelPostProcessActive[traceno] = false; + m_channelPostProcessVoltsMult[traceno] = 1; m_traceControlWidgetList[traceno] = NULL; + m_tracePostProcessControlWidgetList[traceno] = NULL; m_voltsDivSet[traceno] = false; m_channelActiveSet[traceno] = false; @@ -520,6 +580,7 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject * // Create widgets m_base = new ScopeBase(widget()); m_traceControlWidgetGrid = new TQGridLayout(m_base->traceControlLayoutWidget); + m_postProcessTraceControlWidgetGrid = new TQGridLayout(m_base->postProcessTraceControlLayoutWidget); m_mathTraceControlWidgetGrid = new TQGridLayout(m_base->mathTraceControlLayoutWidget); m_timebaseControlWidgetGrid = new TQGridLayout(m_base->timebaseControlLayoutWidget); m_timebaseControlWidget = new TimebaseControlWidget(m_base->timebaseControlLayoutWidget); @@ -2134,15 +2195,19 @@ void ScopePart::recallWaveforms() { TQDataStream ds(&file); TQ_INT32 magicNumber; TQ_INT32 version; + TQ_INT16 savedMaxNumberOfMathTraces; ds >> magicNumber; if (magicNumber == WAVEFORM_MAGIC_NUMBER) { ds >> version; if ((version >= 1) && (version <= WAVEFORM_FILE_VERSION)) { ds >> m_hdivs; ds >> m_vdivs; - ds >> m_maxNumberOfTraces; + ds >> savedMaxNumberOfMathTraces; if (version >= 3) { - ds >> m_maxNumberOfMathTraces; + ds >> savedMaxNumberOfMathTraces; + if (savedMaxNumberOfMathTraces > m_maxNumberOfMathTraces) { + m_maxNumberOfMathTraces = savedMaxNumberOfMathTraces; + } } for (int traceno=1; traceno<=m_maxNumberOfTraces; traceno++) { TQ_UINT8 boolValue; @@ -2169,7 +2234,7 @@ void ScopePart::recallWaveforms() { m_base->traceZoomWidget->setTraceOffset(traceno-1, offset); } if (version >= 3) { - for (int traceno=1; traceno<=m_maxNumberOfMathTraces; traceno++) { + for (int traceno=1; traceno<=savedMaxNumberOfMathTraces; traceno++) { TQ_UINT8 boolValue; ds >> boolValue; m_mathChannelActive[traceno] = (boolValue!=0)?true:false; @@ -2184,6 +2249,13 @@ void ScopePart::recallWaveforms() { m_base->traceZoomWidget->setTraceOffset(traceno-1+m_maxNumberOfTraces, offset); } } + for (int traceno=savedMaxNumberOfMathTraces+1; traceno<=m_maxNumberOfMathTraces; traceno++) { + m_mathChannelActive[traceno] = false; + m_mathVoltsDiv[traceno] = m_mathTraceAllowedVoltsDiv[traceno][0]; + m_mathFirstOperand[traceno] = 1; + m_mathSecondOperand[traceno] = 1; + m_mathOperator[traceno] = "+"; + } } for (int cursorno=0; cursorno<5; cursorno++) { double cursorPos; @@ -2359,12 +2431,24 @@ void ScopePart::updateTraceControlWidgets() { m_traceControlWidgetList[i]->setTraceName(i18n("Channel %1").arg(i+1)); m_traceControlWidgetList[i]->show(); } + if (!m_tracePostProcessControlWidgetList[i]) { + m_tracePostProcessControlWidgetList[i] = new TracePostProcessControlWidget(m_base->postProcessTraceControlLayoutWidget); + connect(m_tracePostProcessControlWidgetList[i], SIGNAL(enableChanged(bool)), this, SLOT(tracePostProcessControlEnableChanged(bool))); + connect(m_tracePostProcessControlWidgetList[i], SIGNAL(voltsMultiplierChanged(double)), this, SLOT(tracePostProcessControlVMultChanged(double))); + m_postProcessTraceControlWidgetGrid->addMultiCellWidget(m_tracePostProcessControlWidgetList[i], i, i, 0, 0); + m_tracePostProcessControlWidgetList[i]->setTraceName(i18n("Channel %1").arg(i+1)); + m_tracePostProcessControlWidgetList[i]->show(); + } } for (i=m_maxNumberOfTraces; iremove(m_traceControlWidgetList[i]); delete m_traceControlWidgetList[i]; } + if (m_tracePostProcessControlWidgetList[i]) { + m_postProcessTraceControlWidgetGrid->remove(m_tracePostProcessControlWidgetList[i]); + delete m_tracePostProcessControlWidgetList[i]; + } } for (i=0; i(sender()); + if (widget) { + for (i=0; i= 0) && (channel <=MAXTRACES)) { + m_channelPostProcessActive[channel+1] = enabled; + if (m_channelPostProcessActive[channel+1]) { + m_traceWidget->setTraceVerticalMultiplier(channel, m_channelPostProcessVoltsMult[channel+1]); + m_base->traceZoomWidget->setTraceVerticalMultiplier(channel, m_channelPostProcessVoltsMult[channel+1]); + } + else { + m_traceWidget->setTraceVerticalMultiplier(channel, 1.0); + m_base->traceZoomWidget->setTraceVerticalMultiplier(channel, 1.0); + } + } + } + + updateGraticule(); + m_traceWidget->repaint(false); + m_base->traceZoomWidget->repaint(false); + updateTraceControlWidgets(); +} + +void ScopePart::tracePostProcessControlVMultChanged(double vmult) { + int i; + int channel = -1; + const TracePostProcessControlWidget* widget = dynamic_cast(sender()); + if (widget) { + for (i=0; i= 0) && (channel <=MAXTRACES)) { + m_channelPostProcessVoltsMult[channel+1] = vmult; + if (m_channelPostProcessActive[channel+1]) { + m_traceWidget->setTraceVerticalMultiplier(channel, m_channelPostProcessVoltsMult[channel+1]); + m_base->traceZoomWidget->setTraceVerticalMultiplier(channel, m_channelPostProcessVoltsMult[channel+1]); + } + else { + m_traceWidget->setTraceVerticalMultiplier(channel, 1.0); + m_base->traceZoomWidget->setTraceVerticalMultiplier(channel, 1.0); + } + } + } + + updateGraticule(); + m_traceWidget->repaint(false); + m_base->traceZoomWidget->repaint(false); + updateTraceControlWidgets(); +} + void ScopePart::mathTraceControlEnableChanged(bool enabled) { int i; int channel = -1; diff --git a/clients/tde/src/part/scope/part.h b/clients/tde/src/part/scope/part.h index c802ebf..2aa2130 100644 --- a/clients/tde/src/part/scope/part.h +++ b/clients/tde/src/part/scope/part.h @@ -15,9 +15,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (c) 2012-2019 Timothy Pearson - * Raptor Engineering - * http://www.raptorengineeringinc.com + * (c) 2012 - 2019 Timothy Pearson + * Raptor Engineering, LLC + * http://www.raptorengineering.com */ #ifndef REMOTELAB_SCOPEPART_H @@ -30,6 +30,8 @@ #include +#include "floatspinbox.h" + #define MAXTRACES 255 #define MAXMATHTRACES 255 @@ -87,6 +89,34 @@ namespace RemoteLab TQDoubleList m_voltsDivList; }; + class TracePostProcessControlWidget : public TQWidget + { + Q_OBJECT + + public: + TracePostProcessControlWidget(TQWidget *parent=0, const char *name=0); + ~TracePostProcessControlWidget(); + + public: + void setSelectedVoltsMultiplier(double vmult); + void setPostProcessEnabled(bool enabled); + void setTraceName(TQString name); + + signals: + void enableChanged(bool enabled); + void voltsMultiplierChanged(double vmult); + + private slots: + void enableClicked(); + void vMultChanged(double vmult); + + private: + TQGroupBox* m_groupBox; + TQGridLayout* m_primaryLayout; + FloatSpinBox* m_voltsMultiplierSpinBox; + TQCheckBox* m_postProcessEnabledCheckBox; + }; + class MathTraceControlWidget : public TQWidget { Q_OBJECT @@ -198,6 +228,8 @@ namespace RemoteLab void traceControlEnableChanged(bool enabled); void traceControlVDivChanged(double vdiv); void traceControlSDivChanged(double sdiv); + void tracePostProcessControlEnableChanged(bool enabled); + void tracePostProcessControlVMultChanged(double vmult); void mathTraceControlEnableChanged(bool enabled); void mathTraceControlVDivChanged(double vdiv); void mathTraceControlFirstOperandChanged(int operand); @@ -219,6 +251,7 @@ namespace RemoteLab TraceWidget* m_traceWidget; TQGridLayout* m_traceControlWidgetGrid; TQGridLayout* m_mathTraceControlWidgetGrid; + TQGridLayout* m_postProcessTraceControlWidgetGrid; TQGridLayout* m_timebaseControlWidgetGrid; int m_commHandlerState; int m_commHandlerMode; @@ -254,6 +287,7 @@ namespace RemoteLab TQString m_mathHorizontalUnits[MAXMATHTRACES+1]; TQString m_mathVerticalUnits[MAXMATHTRACES+1]; TraceControlWidget* m_traceControlWidgetList[MAXTRACES+1]; + TracePostProcessControlWidget* m_tracePostProcessControlWidgetList[MAXTRACES+1]; MathTraceControlWidget* m_mathTraceControlWidgetList[MAXMATHTRACES+1]; TimebaseControlWidget* m_timebaseControlWidget; bool m_triggerLevelSet; @@ -262,6 +296,8 @@ namespace RemoteLab bool m_runningSet; bool m_voltsDivSet[MAXTRACES+1]; bool m_channelActiveSet[MAXTRACES+1]; + bool m_channelPostProcessActive[MAXTRACES+1]; + double m_channelPostProcessVoltsMult[MAXTRACES+1]; bool m_settingsChanged; MathOperatorList m_availableMathOperators; ScopeBase* m_base; diff --git a/clients/tde/src/widgets/tracewidget.cpp b/clients/tde/src/widgets/tracewidget.cpp index f875571..f4a7c7d 100644 --- a/clients/tde/src/widgets/tracewidget.cpp +++ b/clients/tde/src/widgets/tracewidget.cpp @@ -15,9 +15,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (c) 2012-2019 Timothy Pearson - * Raptor Engineering - * http://www.raptorengineeringinc.com + * (c) 2012 - 2019 Timothy Pearson + * Raptor Engineering, LLC + * http://www.raptorengineering.com */ #include "tracewidget.h" @@ -548,6 +548,7 @@ TraceData::TraceData(TraceWidget* parent, TQWidget* labelParent) : TQObject(), p rightEdgeIndex = -1; offset = 0.0; textOffset = 0.0; + verticalMultiplier = 1.0; leftEdge = 0; rightEdge = 0; topEdge = 0; @@ -705,9 +706,9 @@ void TraceData::drawTrace(TQPainter* p, int graticule_width, int graticule_heigh } x = (((positionArray[n]-leftEdge)/(rightEdge-leftEdge))*(virtual_width))-horizoffset; - y = ((((sampleArray[n]+offset)-topEdge)/(bottomEdge-topEdge))*(virtual_height)); + y = (((((sampleArray[n]*verticalMultiplier)+offset)-topEdge)/(bottomEdge-topEdge))*(virtual_height)); x2 = (((positionArray[n+incr]-leftEdge)/(rightEdge-leftEdge))*(virtual_width))-horizoffset; - y2 = ((((sampleArray[n+incr]+offset)-topEdge)/(bottomEdge-topEdge))*(virtual_height)); + y2 = (((((sampleArray[n+incr]*verticalMultiplier)+offset)-topEdge)/(bottomEdge-topEdge))*(virtual_height)); baseline = ((((offset)-topEdge)/(bottomEdge-topEdge))*(virtual_height)); // Do not draw lines that are placed fully off the screen @@ -2493,6 +2494,27 @@ void TraceWidget::setTraceTextOffset(uint traceNumber, double offset, bool defer } } +double TraceWidget::traceVerticalMultiplier(uint traceNumber) { + VERIFY_TRACE_ARRAY_SIZE + + return m_traceArray[traceNumber]->verticalMultiplier; +} + +void TraceWidget::setTraceVerticalMultiplier(uint traceNumber, double verticalMultiplier) { + setTraceVerticalMultiplier(traceNumber, verticalMultiplier, false); +} + +void TraceWidget::setTraceVerticalMultiplier(uint traceNumber, double verticalMultiplier, bool deferUpdate) { + VERIFY_TRACE_ARRAY_SIZE + + m_traceArray[traceNumber]->verticalMultiplier = verticalMultiplier; + + if (!deferUpdate) { + m_graticuleWidget->repaint(false); + updateTraceText(); + } +} + void TraceWidget::processChangedOffset(double offset) { // Find the sending trace number const TraceData* sendingTrace = dynamic_cast(sender()); diff --git a/clients/tde/src/widgets/tracewidget.h b/clients/tde/src/widgets/tracewidget.h index 7f63307..aed6189 100644 --- a/clients/tde/src/widgets/tracewidget.h +++ b/clients/tde/src/widgets/tracewidget.h @@ -15,9 +15,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (c) 2012-2019 Timothy Pearson - * Raptor Engineering - * http://www.raptorengineeringinc.com + * (c) 2012 - 2019 Timothy Pearson + * Raptor Engineering, LLC + * http://www.raptorengineering.com */ #ifndef REMOTELAB_TRACEWIDGET_H @@ -116,6 +116,7 @@ class TraceData : public TQObject long rightEdgeIndex; double offset; double textOffset; + double verticalMultiplier; TQColor color; bool enabled; double leftEdge; @@ -320,6 +321,9 @@ class TraceWidget : public TQWidget double traceTextOffset(uint traceNumber); void setTraceTextOffset(uint traceNumber, double offset, bool deferUpdate); + double traceVerticalMultiplier(uint traceNumber); + void setTraceVerticalMultiplier(uint traceNumber, double verticalMultiplier, bool deferUpdate); + bool horizontalRangeModeAbsolute(); void setHorizontalRangeModeAbsolute(bool absolute=true); @@ -333,6 +337,7 @@ class TraceWidget : public TQWidget public slots: void setTraceOffset(uint traceNumber, double offset); void setTraceTextOffset(uint traceNumber, double offset); + void setTraceVerticalMultiplier(uint traceNumber, double verticalMultiplier); private slots: void updateTraceText();