diff options
author | Tom Rondeau <tom@trondeau.com> | 2015-03-25 00:09:20 -0700 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2015-03-29 14:07:17 -0700 |
commit | c117e3232b32bb70d268932bcea025feb0a4cf25 (patch) | |
tree | f30fe4b276293992847efdb386286590919d9b68 | |
parent | 603e1b2931a91b1718e0300cdade5e796ff12374 (diff) |
qtgui: wip: adding control panel to time display.
- Handles setting autoscale, grid, x and y axis, and trigger modes.
- Uses a new TimeControlPanel class to make it easy to insert and
delete the control panel.
- Toggle to turn on and off a new setting in the parameters box in
GRC.
- Pop-up menu and control panel should be sync'd with signals/slots.
- Shows a dotted red cross-hair for the trigger when set to Auto or
Normal.
-rw-r--r-- | gr-qtgui/grc/qtgui_time_sink_x.xml | 22 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/TimeDomainDisplayPlot.h | 7 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/displayform.h | 1 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/time_sink_c.h | 1 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/time_sink_f.h | 1 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/timecontrolpanel.h | 81 | ||||
-rw-r--r-- | gr-qtgui/include/gnuradio/qtgui/timedisplayform.h | 27 | ||||
-rw-r--r-- | gr-qtgui/lib/CMakeLists.txt | 2 | ||||
-rw-r--r-- | gr-qtgui/lib/TimeDomainDisplayPlot.cc | 43 | ||||
-rw-r--r-- | gr-qtgui/lib/displayform.cc | 5 | ||||
-rw-r--r-- | gr-qtgui/lib/time_sink_c_impl.cc | 9 | ||||
-rw-r--r-- | gr-qtgui/lib/time_sink_c_impl.h | 1 | ||||
-rw-r--r-- | gr-qtgui/lib/time_sink_f_impl.cc | 9 | ||||
-rw-r--r-- | gr-qtgui/lib/time_sink_f_impl.h | 1 | ||||
-rw-r--r-- | gr-qtgui/lib/timecontrolpanel.cc | 183 | ||||
-rw-r--r-- | gr-qtgui/lib/timedisplayform.cc | 222 |
17 files changed, 609 insertions, 7 deletions
diff --git a/gr-qtgui/grc/qtgui_time_sink_x.xml b/gr-qtgui/grc/qtgui_time_sink_x.xml index 2d1cc6552e..adcad507a7 100644 --- a/gr-qtgui/grc/qtgui_time_sink_x.xml +++ b/gr-qtgui/grc/qtgui_time_sink_x.xml @@ -27,6 +27,7 @@ self.$(id).enable_tags(-1, $entags) self.$(id).set_trigger_mode($tr_mode, $tr_slope, $tr_level, $tr_delay, $tr_chan, $tr_tag) self.$(id).enable_autoscale($autoscale) self.$(id).enable_grid($grid) +self.$(id).enable_control_panel($ctrlpanel) labels = [$label1, $label2, $label3, $label4, $label5, $label6, $label7, $label8, $label9, $label10] @@ -167,6 +168,7 @@ $(gui_hint()($win))</make> <type>float</type> <hide>part</hide> </param> + <param> <name>Y max</name> <key>ymax</key> @@ -174,6 +176,7 @@ $(gui_hint()($win))</make> <type>float</type> <hide>part</hide> </param> + <param> <name>Number of Inputs</name> <key>nconnections</key> @@ -181,6 +184,7 @@ $(gui_hint()($win))</make> <type>int</type> <hide>part</hide> </param> + <param> <name>Update Period</name> <key>update_time</key> @@ -188,6 +192,23 @@ $(gui_hint()($win))</make> <type>float</type> <hide>part</hide> </param> + + <param> + <name>Control Panel</name> + <key>ctrlpanel</key> + <value>False</value> + <type>enum</type> + <hide>part</hide> + <option> + <name>Yes</name> + <key>True</key> + </option> + <option> + <name>No</name> + <key>False</key> + </option> + </param> + <param> <name>Disp. Tags</name> <key>entags</key> @@ -203,6 +224,7 @@ $(gui_hint()($win))</make> <key>False</key> </option> </param> + <param> <name>GUI Hint</name> <key>gui_hint</key> diff --git a/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt b/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt index 43cee2f0a7..6ba992363d 100644 --- a/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt +++ b/gr-qtgui/include/gnuradio/qtgui/CMakeLists.txt @@ -48,6 +48,7 @@ install(FILES SpectrumGUIClass.h spectrumUpdateEvents.h timedisplayform.h + timecontrolpanel.h TimeDomainDisplayPlot.h timerasterdisplayform.h TimeRasterDisplayPlot.h diff --git a/gr-qtgui/include/gnuradio/qtgui/TimeDomainDisplayPlot.h b/gr-qtgui/include/gnuradio/qtgui/TimeDomainDisplayPlot.h index 81601cee97..3a51888a63 100644 --- a/gr-qtgui/include/gnuradio/qtgui/TimeDomainDisplayPlot.h +++ b/gr-qtgui/include/gnuradio/qtgui/TimeDomainDisplayPlot.h @@ -50,6 +50,8 @@ public: void stemPlot(bool en); + double sampleRate() const; + public slots: void setSampleRate(double sr, double units, const std::string &strunits); @@ -66,6 +68,9 @@ public slots: void setYLabel(const std::string &label, const std::string &unit=""); + void attachTriggerLines(bool en); + void setTriggerLines(double x, double y); + private: void _resetXAxisPoints(); void _autoScale(double bottom, double top); @@ -80,6 +85,8 @@ private: std::vector< std::vector<QwtPlotMarker*> > d_tag_markers; std::vector<bool> d_tag_markers_en; + + QwtPlotMarker *d_trigger_lines[2]; }; #endif /* TIME_DOMAIN_DISPLAY_PLOT_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/displayform.h b/gr-qtgui/include/gnuradio/qtgui/displayform.h index 42c8e40e3d..02d2cf8cd4 100644 --- a/gr-qtgui/include/gnuradio/qtgui/displayform.h +++ b/gr-qtgui/include/gnuradio/qtgui/displayform.h @@ -95,6 +95,7 @@ private slots: signals: void plotPointSelected(const QPointF p, int type); + void toggleGrid(bool en); protected: bool d_isclosed; diff --git a/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h b/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h index 84a8a4dd5a..907fd3f07d 100644 --- a/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h +++ b/gr-qtgui/include/gnuradio/qtgui/time_sink_c.h @@ -157,6 +157,7 @@ namespace gr { virtual void enable_stem_plot(bool en=true) = 0; virtual void enable_semilogx(bool en=true) = 0; virtual void enable_semilogy(bool en=true) = 0; + virtual void enable_control_panel(bool en=true) = 0; virtual void enable_tags(int which, bool en) = 0; virtual int nsamps() const = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h b/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h index b39c898e66..f4bb4157f0 100644 --- a/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h +++ b/gr-qtgui/include/gnuradio/qtgui/time_sink_f.h @@ -147,6 +147,7 @@ namespace gr { virtual void enable_stem_plot(bool en=true) = 0; virtual void enable_semilogx(bool en=true) = 0; virtual void enable_semilogy(bool en=true) = 0; + virtual void enable_control_panel(bool en=true) = 0; virtual void enable_tags(int which, bool en) = 0; virtual int nsamps() const = 0; diff --git a/gr-qtgui/include/gnuradio/qtgui/timecontrolpanel.h b/gr-qtgui/include/gnuradio/qtgui/timecontrolpanel.h new file mode 100644 index 0000000000..6f8800c8dd --- /dev/null +++ b/gr-qtgui/include/gnuradio/qtgui/timecontrolpanel.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2015 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef TIME_CONTROL_PANEL_H +#define TIME_CONTROL_PANEL_H + +#include <QtGui/QtGui> +#include <vector> +#include <QSlider> +#include <QComboBox> +#include <QCheckBox> +#include <QPushButton> +#include <QLabel> +#include <QHBoxLayout> +#include <gnuradio/qtgui/displayform.h> +#include <gnuradio/qtgui/timedisplayform.h> + +class TimeControlPanel : public QVBoxLayout +{ + Q_OBJECT + +public: + TimeControlPanel(TimeDisplayForm *form); + ~TimeControlPanel(); + +public slots: + void toggleAutoScale(bool en); + void toggleGrid(bool en); + void toggleTriggerMode(gr::qtgui::trigger_mode mode); + void toggleTriggerSlope(gr::qtgui::trigger_slope slope); + +private: + TimeDisplayForm *d_parent; + QGroupBox *d_axes_box; + QGroupBox *d_trigger_box; + + QVBoxLayout *d_axes_layout; + QHBoxLayout *d_yoff_layout; + QHBoxLayout *d_yrange_layout; + QHBoxLayout *d_xmax_layout; + QVBoxLayout *d_trigger_layout; + QHBoxLayout *d_trigger_level_layout; + QHBoxLayout *d_trigger_delay_layout; + + QLabel *d_yoff_label; + QLabel *d_yrange_label; + QLabel *d_xmax_label; + QLabel *d_trigger_level_label; + QLabel *d_trigger_delay_label; + + QCheckBox *d_autorange_check; + QCheckBox *d_grid_check; + QPushButton *d_yoff_plus, *d_yoff_minus; + QPushButton *d_yrange_plus, *d_yrange_minus; + QPushButton *d_xmax_plus, *d_xmax_minus; + QComboBox *d_trigger_mode_combo; + QComboBox *d_trigger_slope_combo; + QPushButton *d_trigger_level_plus, *d_trigger_level_minus; + QPushButton *d_trigger_delay_plus, *d_trigger_delay_minus; +}; + +#endif /* TIME_CONTROL_PANEL_H */ diff --git a/gr-qtgui/include/gnuradio/qtgui/timedisplayform.h b/gr-qtgui/include/gnuradio/qtgui/timedisplayform.h index e52e28c3d6..a52e1bfc8b 100644 --- a/gr-qtgui/include/gnuradio/qtgui/timedisplayform.h +++ b/gr-qtgui/include/gnuradio/qtgui/timedisplayform.h @@ -25,10 +25,11 @@ #include <gnuradio/qtgui/spectrumUpdateEvents.h> #include <gnuradio/qtgui/TimeDomainDisplayPlot.h> +#include <gnuradio/qtgui/displayform.h> #include <QtGui/QtGui> #include <vector> -#include <gnuradio/qtgui/displayform.h> +class TimeControlPanel; /*! * \brief DisplayForm child for managing time domain plots. @@ -38,7 +39,7 @@ class TimeDisplayForm : public DisplayForm { Q_OBJECT - public: +public: TimeDisplayForm(int nplots=1, QWidget* parent = 0); ~TimeDisplayForm(); @@ -79,14 +80,34 @@ public slots: void setTriggerTagKey(QString s); void setTriggerTagKey(const std::string &s); + void teardownControlPanel(); + void setupControlPanel(); + private slots: void newData(const QEvent*); + void notifyYAxisPlus(); + void notifyYAxisMinus(); + void notifyYRangePlus(); + void notifyYRangeMinus(); + void notifyXAxisPlus(); + void notifyXAxisMinus(); + void notifyTriggerMode(const QString &mode); + void notifyTriggerSlope(const QString &slope); + void notifyTriggerLevelPlus(); + void notifyTriggerLevelMinus(); + void notifyTriggerDelayPlus(); + void notifyTriggerDelayMinus(); + +signals: + void signalTriggerMode(gr::qtgui::trigger_mode mode); + void signalTriggerSlope(gr::qtgui::trigger_slope slope); private: QIntValidator* d_int_validator; double d_start_frequency; double d_stop_frequency; + double d_current_units; int d_npoints; @@ -114,6 +135,8 @@ private: float d_trig_delay; int d_trig_channel; std::string d_trig_tag_key; + + TimeControlPanel *d_controlpanel; }; #endif /* TIME_DISPLAY_FORM_H */ diff --git a/gr-qtgui/lib/CMakeLists.txt b/gr-qtgui/lib/CMakeLists.txt index 57970b28ee..636ae3d0e9 100644 --- a/gr-qtgui/lib/CMakeLists.txt +++ b/gr-qtgui/lib/CMakeLists.txt @@ -25,6 +25,7 @@ set(qtgui_moc_hdrs ${qtgui_mod_includedir}/spectrumdisplayform.h ${qtgui_mod_includedir}/displayform.h ${qtgui_mod_includedir}/timedisplayform.h + ${qtgui_mod_includedir}/timecontrolpanel.h ${qtgui_mod_includedir}/timerasterdisplayform.h ${qtgui_mod_includedir}/freqdisplayform.h ${qtgui_mod_includedir}/constellationdisplayform.h @@ -68,6 +69,7 @@ set(qtgui_sources spectrumdisplayform.cc displayform.cc timedisplayform.cc + timecontrolpanel.cc timerasterdisplayform.cc freqdisplayform.cc constellationdisplayform.cc diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.cc b/gr-qtgui/lib/TimeDomainDisplayPlot.cc index 7b81c86d2e..2602c0a609 100644 --- a/gr-qtgui/lib/TimeDomainDisplayPlot.cc +++ b/gr-qtgui/lib/TimeDomainDisplayPlot.cc @@ -195,8 +195,23 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(int nplots, QWidget* parent) d_tag_markers.resize(d_nplots); d_tag_markers_en = std::vector<bool>(d_nplots, true); + + d_trigger_lines[0] = new QwtPlotMarker(); + d_trigger_lines[0]->setLineStyle(QwtPlotMarker::HLine); + d_trigger_lines[0]->setLinePen(QPen(Qt::red, 0.6, Qt::DashLine)); + d_trigger_lines[0]->setRenderHint(QwtPlotItem::RenderAntialiased); + d_trigger_lines[0]->setXValue(0.0); + d_trigger_lines[0]->setYValue(0.0); + + d_trigger_lines[1] = new QwtPlotMarker(); + d_trigger_lines[1]->setLineStyle(QwtPlotMarker::VLine); + d_trigger_lines[1]->setLinePen(QPen(Qt::red, 0.6, Qt::DashLine)); + d_trigger_lines[1]->setRenderHint(QwtPlotItem::RenderAntialiased); + d_trigger_lines[1]->setXValue(0.0); + d_trigger_lines[1]->setYValue(0.0); } + TimeDomainDisplayPlot::~TimeDomainDisplayPlot() { for(int i = 0; i < d_nplots; i++) @@ -494,6 +509,12 @@ TimeDomainDisplayPlot::setSampleRate(double sr, double units, } } +double +TimeDomainDisplayPlot::sampleRate() const +{ + return d_sample_rate; +} + void TimeDomainDisplayPlot::stemPlot(bool en) { @@ -575,4 +596,26 @@ TimeDomainDisplayPlot::setYLabel(const std::string &label, ((TimeDomainDisplayZoomer*)d_zoomer)->setYUnitType(unit); } +void +TimeDomainDisplayPlot::attachTriggerLines(bool en) +{ + if(en) { + d_trigger_lines[0]->attach(this); + d_trigger_lines[1]->attach(this); + } + else { + d_trigger_lines[0]->detach(); + d_trigger_lines[1]->detach(); + } +} + +void +TimeDomainDisplayPlot::setTriggerLines(double x, double y) +{ + d_trigger_lines[0]->setXValue(x); + d_trigger_lines[0]->setYValue(y); + d_trigger_lines[1]->setXValue(x); + d_trigger_lines[1]->setYValue(y); +} + #endif /* TIME_DOMAIN_DISPLAY_PLOT_C */ diff --git a/gr-qtgui/lib/displayform.cc b/gr-qtgui/lib/displayform.cc index b811801201..bbf415ff40 100644 --- a/gr-qtgui/lib/displayform.cc +++ b/gr-qtgui/lib/displayform.cc @@ -135,8 +135,8 @@ DisplayForm::~DisplayForm() void DisplayForm::resizeEvent( QResizeEvent *e ) { - QSize s = size(); - emit d_display_plot->resizeSlot(&s); + //QSize s = size(); + //emit d_display_plot->resizeSlot(&s); } void @@ -331,6 +331,7 @@ DisplayForm::setGrid(bool on) d_grid->detach(); d_grid_state = false; } + d_grid_act->setChecked(on); d_display_plot->replot(); } diff --git a/gr-qtgui/lib/time_sink_c_impl.cc b/gr-qtgui/lib/time_sink_c_impl.cc index c9f8d7783a..951557790f 100644 --- a/gr-qtgui/lib/time_sink_c_impl.cc +++ b/gr-qtgui/lib/time_sink_c_impl.cc @@ -397,6 +397,15 @@ namespace gr { } void + time_sink_c_impl::enable_control_panel(bool en) + { + if(en) + d_main_gui->setupControlPanel(); + else + d_main_gui->teardownControlPanel(); + } + + void time_sink_c_impl::enable_tags(int which, bool en) { if(which == -1) { diff --git a/gr-qtgui/lib/time_sink_c_impl.h b/gr-qtgui/lib/time_sink_c_impl.h index 378296918d..5c0f1c95c5 100644 --- a/gr-qtgui/lib/time_sink_c_impl.h +++ b/gr-qtgui/lib/time_sink_c_impl.h @@ -124,6 +124,7 @@ namespace gr { void enable_stem_plot(bool en); void enable_semilogx(bool en); void enable_semilogy(bool en); + void enable_control_panel(bool en); void enable_tags(int which, bool en); void reset(); diff --git a/gr-qtgui/lib/time_sink_f_impl.cc b/gr-qtgui/lib/time_sink_f_impl.cc index 8e45e2c941..b730eb512d 100644 --- a/gr-qtgui/lib/time_sink_f_impl.cc +++ b/gr-qtgui/lib/time_sink_f_impl.cc @@ -399,6 +399,15 @@ namespace gr { } void + time_sink_f_impl::enable_control_panel(bool en) + { + if(en) + d_main_gui->setupControlPanel(); + else + d_main_gui->teardownControlPanel(); + } + + void time_sink_f_impl::enable_tags(int which, bool en) { if(which == -1) { diff --git a/gr-qtgui/lib/time_sink_f_impl.h b/gr-qtgui/lib/time_sink_f_impl.h index 2da1db97d1..a9f63e3b3b 100644 --- a/gr-qtgui/lib/time_sink_f_impl.h +++ b/gr-qtgui/lib/time_sink_f_impl.h @@ -124,6 +124,7 @@ namespace gr { void enable_stem_plot(bool en); void enable_semilogx(bool en); void enable_semilogy(bool en); + void enable_control_panel(bool en); void enable_tags(int which, bool en); void reset(); diff --git a/gr-qtgui/lib/timecontrolpanel.cc b/gr-qtgui/lib/timecontrolpanel.cc new file mode 100644 index 0000000000..ab96a41a9d --- /dev/null +++ b/gr-qtgui/lib/timecontrolpanel.cc @@ -0,0 +1,183 @@ +/* -*- c++ -*- */ +/* + * Copyright 2015 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <gnuradio/qtgui/timecontrolpanel.h> + +TimeControlPanel::TimeControlPanel(TimeDisplayForm *form) + : QVBoxLayout(), + d_parent(form) +{ + // Set up the box for axes items + d_axes_box = new QGroupBox("Axes"); + d_axes_layout = new QVBoxLayout; + d_autorange_check = new QCheckBox("Autorange"); + d_grid_check = new QCheckBox("Grid"); + + d_yoff_layout = new QHBoxLayout; + d_yoff_label = new QLabel("Y Offset:"); + d_yoff_plus = new QPushButton("+"); + d_yoff_minus = new QPushButton("-"); + d_yoff_plus->setMaximumWidth(30); + d_yoff_minus->setMaximumWidth(30); + d_yoff_layout->addWidget(d_yoff_label); + d_yoff_layout->addWidget(d_yoff_plus); + d_yoff_layout->addWidget(d_yoff_minus); + + d_yrange_layout = new QHBoxLayout; + d_yrange_label = new QLabel("Y Range:"); + d_yrange_plus = new QPushButton("+"); + d_yrange_minus = new QPushButton("-"); + d_yrange_plus->setMaximumWidth(30); + d_yrange_minus->setMaximumWidth(30); + d_yrange_layout->addWidget(d_yrange_label); + d_yrange_layout->addWidget(d_yrange_plus); + d_yrange_layout->addWidget(d_yrange_minus); + + d_xmax_layout = new QHBoxLayout; + d_xmax_label = new QLabel("X Max:"); + d_xmax_plus = new QPushButton("+"); + d_xmax_minus = new QPushButton("-"); + d_xmax_plus->setMaximumWidth(30); + d_xmax_minus->setMaximumWidth(30); + d_xmax_layout->addWidget(d_xmax_label); + d_xmax_layout->addWidget(d_xmax_plus); + d_xmax_layout->addWidget(d_xmax_minus); + + + // Set up the box for trigger items + d_trigger_box = new QGroupBox("Trigger"); + d_trigger_layout = new QVBoxLayout; + d_trigger_mode_combo = new QComboBox(); + d_trigger_mode_combo->addItem("Free"); + d_trigger_mode_combo->addItem("Auto"); + d_trigger_mode_combo->addItem("Normal"); + d_trigger_mode_combo->addItem("Tag"); + + d_trigger_slope_combo = new QComboBox(); + d_trigger_slope_combo->addItem("Positive"); + d_trigger_slope_combo->addItem("Negative"); + + d_trigger_level_layout = new QHBoxLayout; + d_trigger_level_label = new QLabel("Level:"); + d_trigger_level_plus = new QPushButton("+"); + d_trigger_level_minus = new QPushButton("-"); + d_trigger_level_plus->setMaximumWidth(30); + d_trigger_level_minus->setMaximumWidth(30); + d_trigger_level_layout->addWidget(d_trigger_level_label); + d_trigger_level_layout->addWidget(d_trigger_level_plus); + d_trigger_level_layout->addWidget(d_trigger_level_minus); + + d_trigger_delay_layout = new QHBoxLayout; + d_trigger_delay_label = new QLabel("Delay:"); + d_trigger_delay_plus = new QPushButton("+"); + d_trigger_delay_minus = new QPushButton("-"); + d_trigger_delay_plus->setMaximumWidth(30); + d_trigger_delay_minus->setMaximumWidth(30); + d_trigger_delay_layout->addWidget(d_trigger_delay_label); + d_trigger_delay_layout->addWidget(d_trigger_delay_plus); + d_trigger_delay_layout->addWidget(d_trigger_delay_minus); + + + // Set up the boxes into the layout + d_axes_layout->addWidget(d_autorange_check); + d_axes_layout->addWidget(d_grid_check); + d_axes_layout->addLayout(d_yoff_layout); + d_axes_layout->addLayout(d_yrange_layout); + d_axes_layout->addLayout(d_xmax_layout); + d_axes_box->setLayout(d_axes_layout); + + d_trigger_layout->addWidget(d_trigger_mode_combo); + d_trigger_layout->addWidget(d_trigger_slope_combo); + d_trigger_layout->addLayout(d_trigger_level_layout); + d_trigger_layout->addLayout(d_trigger_delay_layout); + d_trigger_box->setLayout(d_trigger_layout); + + addWidget(d_axes_box); + addWidget(d_trigger_box); + addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, + QSizePolicy::Expanding)); + + connect(d_autorange_check, SIGNAL(clicked(bool)), + d_parent, SLOT(autoScale(bool))); + connect(d_grid_check, SIGNAL(clicked(bool)), + d_parent, SLOT(setGrid(bool))); + connect(d_yoff_plus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyYAxisPlus(void))); + connect(d_yoff_minus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyYAxisMinus(void))); + + connect(d_yrange_plus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyYRangePlus(void))); + connect(d_yrange_minus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyYRangeMinus(void))); + + connect(d_xmax_plus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyXAxisPlus(void))); + connect(d_xmax_minus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyXAxisMinus(void))); + connect(d_trigger_mode_combo, SIGNAL(currentIndexChanged(const QString&)), + d_parent, SLOT(notifyTriggerMode(const QString&))); + connect(d_trigger_slope_combo, SIGNAL(currentIndexChanged(const QString&)), + d_parent, SLOT(notifyTriggerSlope(const QString&))); + connect(d_trigger_level_plus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyTriggerLevelPlus())); + connect(d_trigger_level_minus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyTriggerLevelMinus())); + connect(d_trigger_delay_plus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyTriggerDelayPlus())); + connect(d_trigger_delay_minus, SIGNAL(pressed(void)), + d_parent, SLOT(notifyTriggerDelayMinus())); +} + +TimeControlPanel::~TimeControlPanel() +{ + removeWidget(d_axes_box); + removeWidget(d_trigger_box); + delete d_axes_box; + delete d_trigger_box; + + // All other children of the boxes are automatically deleted. +} + +void +TimeControlPanel::toggleAutoScale(bool en) +{ + d_autorange_check->setChecked(en); +} + +void +TimeControlPanel::toggleGrid(bool en) +{ + d_grid_check->setChecked(en); +} + +void +TimeControlPanel::toggleTriggerMode(gr::qtgui::trigger_mode mode) +{ + d_trigger_mode_combo->setCurrentIndex(static_cast<int>(mode)); +} + +void +TimeControlPanel::toggleTriggerSlope(gr::qtgui::trigger_slope slope) +{ + d_trigger_slope_combo->setCurrentIndex(static_cast<int>(slope)); +} diff --git a/gr-qtgui/lib/timedisplayform.cc b/gr-qtgui/lib/timedisplayform.cc index 6d1deba05f..c9414a22cb 100644 --- a/gr-qtgui/lib/timedisplayform.cc +++ b/gr-qtgui/lib/timedisplayform.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2011,2012 Free Software Foundation, Inc. + * Copyright 2011,2012,2015 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,22 +22,33 @@ #include <cmath> #include <QMessageBox> +#include <QSpacerItem> +#include <QGroupBox> #include <gnuradio/qtgui/timedisplayform.h> +#include <gnuradio/qtgui/timecontrolpanel.h> #include <iostream> + TimeDisplayForm::TimeDisplayForm(int nplots, QWidget* parent) : DisplayForm(nplots, parent) { d_stem = false; d_semilogx = false; d_semilogy = false; + d_current_units = 1; d_int_validator = new QIntValidator(this); d_int_validator->setBottom(0); d_layout = new QGridLayout(this); d_display_plot = new TimeDomainDisplayPlot(nplots, this); + + d_controlpanel = NULL; + + // Setup the layout of the display d_layout->addWidget(d_display_plot, 0, 0); + + d_layout->setColumnStretch(0, 1); setLayout(d_layout); d_nptsmenu = new NPointsMenu(this); @@ -89,13 +100,14 @@ TimeDisplayForm::TimeDisplayForm(int nplots, QWidget* parent) d_menu->addMenu(d_triggermenu); setTriggerMode(gr::qtgui::TRIG_MODE_FREE); + setTriggerSlope(gr::qtgui::TRIG_SLOPE_POS); + connect(d_tr_mode_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_mode)), this, SLOT(setTriggerMode(gr::qtgui::trigger_mode))); // updates trigger state by calling set level or set tag key. connect(d_tr_mode_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_mode)), this, SLOT(updateTrigger(gr::qtgui::trigger_mode))); - setTriggerSlope(gr::qtgui::TRIG_SLOPE_POS); connect(d_tr_slope_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_slope)), this, SLOT(setTriggerSlope(gr::qtgui::trigger_slope))); @@ -127,6 +139,46 @@ TimeDisplayForm::~TimeDisplayForm() // Don't worry about deleting Display Plots - they are deleted when parents are deleted delete d_int_validator; + + teardownControlPanel(); +} + + +void +TimeDisplayForm::setupControlPanel() +{ + // Create the control panel layout + d_controlpanel = new TimeControlPanel(this); + + // Connect action items in menu to controlpanel widgets + connect(d_autoscale_act, SIGNAL(triggered(bool)), + d_controlpanel, SLOT(toggleAutoScale(bool))); + connect(d_grid_act, SIGNAL(triggered(bool)), + d_controlpanel, SLOT(toggleGrid(bool))); + connect(d_tr_mode_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_mode)), + d_controlpanel, SLOT(toggleTriggerMode(gr::qtgui::trigger_mode))); + connect(this, SIGNAL(signalTriggerMode(gr::qtgui::trigger_mode)), + d_controlpanel, SLOT(toggleTriggerMode(gr::qtgui::trigger_mode))); + connect(d_tr_slope_menu, SIGNAL(whichTrigger(gr::qtgui::trigger_slope)), + d_controlpanel, SLOT(toggleTriggerSlope(gr::qtgui::trigger_slope))); + connect(this, SIGNAL(signalTriggerSlope(gr::qtgui::trigger_slope)), + d_controlpanel, SLOT(toggleTriggerSlope(gr::qtgui::trigger_slope))); + d_layout->addLayout(d_controlpanel, 0, 1); + + d_controlpanel->toggleAutoScale(d_autoscale_act->isChecked()); + d_controlpanel->toggleGrid(d_grid_act->isChecked()); + d_controlpanel->toggleTriggerMode(getTriggerMode()); + d_controlpanel->toggleTriggerSlope(getTriggerSlope()); +} + +void +TimeDisplayForm::teardownControlPanel() +{ + if(d_controlpanel) { + d_layout->removeItem(d_controlpanel); + delete d_controlpanel; + d_controlpanel = NULL; + } } TimeDomainDisplayPlot* @@ -173,6 +225,8 @@ TimeDisplayForm::setSampleRate(const double samprate) double units = pow(10, (units10-fmod(units10, 3.0))); int iunit = static_cast<int>(units3); + d_current_units = units; + getPlot()->setSampleRate(samprate, units, strtime[iunit]); } else { @@ -267,18 +321,34 @@ TimeDisplayForm::setTriggerMode(gr::qtgui::trigger_mode mode) { d_trig_mode = mode; d_tr_mode_menu->getAction(mode)->setChecked(true); + + if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == gr::qtgui::TRIG_MODE_NORM)) { + getPlot()->attachTriggerLines(true); + } + else { + getPlot()->attachTriggerLines(false); + } + + emit signalTriggerMode(mode); } void TimeDisplayForm::updateTrigger(gr::qtgui::trigger_mode mode) { // If auto or normal mode, popup trigger level box to set - if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == gr::qtgui::TRIG_MODE_NORM)) + if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == gr::qtgui::TRIG_MODE_NORM)) { d_tr_level_act->activate(QAction::Trigger); + getPlot()->attachTriggerLines(true); + } + else { + getPlot()->attachTriggerLines(false); + } // if tag mode, popup tag key box to set if(d_trig_mode == gr::qtgui::TRIG_MODE_TAG) d_tr_tag_key_act->activate(QAction::Trigger); + + emit signalTriggerMode(mode); } gr::qtgui::trigger_mode @@ -292,6 +362,8 @@ TimeDisplayForm::setTriggerSlope(gr::qtgui::trigger_slope slope) { d_trig_slope = slope; d_tr_slope_menu->getAction(slope)->setChecked(true); + + emit signalTriggerSlope(slope); } gr::qtgui::trigger_slope @@ -304,6 +376,10 @@ void TimeDisplayForm::setTriggerLevel(QString s) { d_trig_level = s.toFloat(); + + if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == gr::qtgui::TRIG_MODE_NORM)) { + getPlot()->setTriggerLines(d_trig_delay*d_current_units, d_trig_level); + } } void @@ -311,6 +387,10 @@ TimeDisplayForm::setTriggerLevel(float level) { d_trig_level = level; d_tr_level_act->setText(QString().setNum(d_trig_level)); + + if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == gr::qtgui::TRIG_MODE_NORM)) { + getPlot()->setTriggerLines(d_trig_delay*d_current_units, d_trig_level); + } } float @@ -323,6 +403,10 @@ void TimeDisplayForm::setTriggerDelay(QString s) { d_trig_delay = s.toFloat(); + + if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == gr::qtgui::TRIG_MODE_NORM)) { + getPlot()->setTriggerLines(d_trig_delay*d_current_units, d_trig_level); + } } void @@ -330,6 +414,10 @@ TimeDisplayForm::setTriggerDelay(float delay) { d_trig_delay = delay; d_tr_delay_act->setText(QString().setNum(d_trig_delay)); + + if((d_trig_mode == gr::qtgui::TRIG_MODE_AUTO) || (d_trig_mode == gr::qtgui::TRIG_MODE_NORM)) { + getPlot()->setTriggerLines(d_trig_delay*d_current_units, d_trig_level); + } } float @@ -369,3 +457,131 @@ TimeDisplayForm::getTriggerTagKey() const { return d_trig_tag_key; } + + + +/******************************************************************** + * Notifcation messages from the control panel + *******************************************************************/ + +void +TimeDisplayForm::notifyYAxisPlus() +{ + QwtScaleDiv *ax = getPlot()->axisScaleDiv(QwtPlot::yLeft); + double range = ax->upperBound() - ax->lowerBound(); + double step = range/20.0; + getPlot()->setYaxis(ax->lowerBound()+step, ax->upperBound()+step); +} + +void +TimeDisplayForm::notifyYAxisMinus() +{ + QwtScaleDiv *ax = getPlot()->axisScaleDiv(QwtPlot::yLeft); + double range = ax->upperBound() - ax->lowerBound(); + double step = range/20.0; + getPlot()->setYaxis(ax->lowerBound()-step, ax->upperBound()-step); +} + +void +TimeDisplayForm::notifyYRangePlus() +{ + QwtScaleDiv *ax = getPlot()->axisScaleDiv(QwtPlot::yLeft); + double range = ax->upperBound() - ax->lowerBound(); + double step = range/20.0; + getPlot()->setYaxis(ax->lowerBound()-step, ax->upperBound()+step); +} + +void +TimeDisplayForm::notifyYRangeMinus() +{ + QwtScaleDiv *ax = getPlot()->axisScaleDiv(QwtPlot::yLeft); + double range = ax->upperBound() - ax->lowerBound(); + double step = range/20.0; + getPlot()->setYaxis(ax->lowerBound()+step, ax->upperBound()-step); +} + + +void +TimeDisplayForm::notifyXAxisPlus() +{ + // increase by 10% + setNPoints(static_cast<int>(1.1*getNPoints())); +} + +void +TimeDisplayForm::notifyXAxisMinus() +{ + // decrease by 10% + setNPoints(static_cast<int>(0.9*getNPoints())); +} + + + +void +TimeDisplayForm::notifyTriggerMode(const QString &mode) +{ + if(mode == "Free") { + setTriggerMode(gr::qtgui::TRIG_MODE_FREE); + } + else if(mode == "Auto") { + setTriggerMode(gr::qtgui::TRIG_MODE_AUTO); + } + else if(mode == "Normal") { + setTriggerMode(gr::qtgui::TRIG_MODE_NORM); + } + else if(mode == "Tag") { + setTriggerMode(gr::qtgui::TRIG_MODE_TAG); + updateTrigger(gr::qtgui::TRIG_MODE_TAG); + } +} + +void +TimeDisplayForm::notifyTriggerSlope(const QString &slope) +{ + if(slope == "Positive") { + setTriggerSlope(gr::qtgui::TRIG_SLOPE_POS); + } + else if(slope == "Negative") { + setTriggerSlope(gr::qtgui::TRIG_SLOPE_NEG); + } +} + +void +TimeDisplayForm::notifyTriggerLevelPlus() +{ + QwtScaleDiv *ax = getPlot()->axisScaleDiv(QwtPlot::yLeft); + double range = ax->upperBound() - ax->lowerBound(); + double step = range/20.0; + setTriggerLevel(getTriggerLevel() + step); +} + +void +TimeDisplayForm::notifyTriggerLevelMinus() +{ + QwtScaleDiv *ax = getPlot()->axisScaleDiv(QwtPlot::yLeft); + double range = ax->upperBound() - ax->lowerBound(); + double step = range/20.0; + setTriggerLevel(getTriggerLevel() - step); +} + +void +TimeDisplayForm::notifyTriggerDelayPlus() +{ + QwtScaleDiv *ax = getPlot()->axisScaleDiv(QwtPlot::xBottom); + double range = ax->upperBound() - ax->lowerBound(); + double step = range/20.0; + double trig = getTriggerDelay() + step / d_current_units; + setTriggerDelay(trig); +} + +void +TimeDisplayForm::notifyTriggerDelayMinus() +{ + QwtScaleDiv *ax = getPlot()->axisScaleDiv(QwtPlot::xBottom); + double range = ax->upperBound() - ax->lowerBound(); + double step = range/20.0; + double trig = getTriggerDelay() - step / d_current_units; + if(trig < 0) + trig = 0; + setTriggerDelay(trig); +} |