/*Copyright © 2017 Hasan Yavuz ÖzderyaThis file is part of serialplot.serialplot is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.serialplot is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with serialplot. If not, see <http://www.gnu.org/licenses/>.*/#include <QVariant>#include <QMessageBox>#include <QCheckBox>#include <math.h>#include "color_selector.hpp"#include "plotcontrolpanel.h"#include "ui_plotcontrolpanel.h"#include "setting_defines.h"/// Confirm if #samples is being set to a value greater than thisconst int NUMSAMPLES_CONFIRM_AT = 1000000;/// Used for scale range selection comboboxstruct Range{double rmin;double rmax;};Q_DECLARE_METATYPE(Range);PlotControlPanel::PlotControlPanel(QWidget *parent) :QWidget(parent),ui(new Ui::PlotControlPanel),resetAct(tr("Reset"), this),resetNamesAct(tr("Reset Names"), this),resetColorsAct(tr("Reset Colors"), this),showAllAct(tr("Show All"), this),resetMenu(tr("Reset Menu"), this){ui->setupUi(this);warnNumOfSamples = true; // TODO: load from settings_numOfSamples = ui->spNumOfSamples->value();// set limits for axis limit boxesui->spYmin->setRange((-1) * std::numeric_limits<double>::max(),std::numeric_limits<double>::max());ui->spYmax->setRange((-1) * std::numeric_limits<double>::max(),std::numeric_limits<double>::max());ui->spXmin->setRange((-1) * std::numeric_limits<double>::max(),std::numeric_limits<double>::max());ui->spXmax->setRange((-1) * std::numeric_limits<double>::max(),std::numeric_limits<double>::max());// connect signalsconnect(ui->spNumOfSamples, SIGNAL(valueChanged(int)),this, SLOT(onNumOfSamples(int)));connect(ui->cbAutoScale, &QCheckBox::toggled,this, &PlotControlPanel::onAutoScaleChecked);connect(ui->spYmax, SIGNAL(valueChanged(double)),this, SLOT(onYScaleChanged()));connect(ui->spYmin, SIGNAL(valueChanged(double)),this, SLOT(onYScaleChanged()));connect(ui->cbIndex, &QCheckBox::toggled,this, &PlotControlPanel::onIndexChecked);connect(ui->spXmax, SIGNAL(valueChanged(double)),this, SLOT(onXScaleChanged()));connect(ui->spXmax, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),[this](double v){// set limit just a little belowdouble step = pow(10, -1 * ui->spXmin->decimals());ui->spXmin->setMaximum(v - step);});connect(ui->spXmin, SIGNAL(valueChanged(double)),this, SLOT(onXScaleChanged()));connect(ui->spXmin, static_cast<void(QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),[this](double v){// set limit just a little abovedouble step = pow(10, -1 * ui->spXmax->decimals());ui->spXmax->setMinimum(v + step);});connect(ui->spPlotWidth, SIGNAL(valueChanged(int)),this, SLOT(onPlotWidthChanged()));// init scale range preset listfor (int nbits = 8; nbits <= 24; nbits++) // signed binary formats{int rmax = pow(2, nbits-1)-1;int rmin = -rmax-1;Range r = {double(rmin), double(rmax)};ui->cbRangePresets->addItem(QString().sprintf("Signed %d bits %d to +%d", nbits, rmin, rmax),QVariant::fromValue(r));}for (int nbits = 8; nbits <= 24; nbits++) // unsigned binary formats{int rmax = pow(2, nbits)-1;ui->cbRangePresets->addItem(QString().sprintf("Unsigned %d bits %d to +%d", nbits, 0, rmax),QVariant::fromValue(Range{0, double(rmax)}));}ui->cbRangePresets->addItem("-1 to +1", QVariant::fromValue(Range{-1, +1}));ui->cbRangePresets->addItem("0 to +1", QVariant::fromValue(Range{0, +1}));ui->cbRangePresets->addItem("-100 to +100", QVariant::fromValue(Range{-100, +100}));ui->cbRangePresets->addItem("0 to +100", QVariant::fromValue(Range{0, +100}));QObject::connect(ui->cbRangePresets, SIGNAL(activated(int)),this, SLOT(onRangeSelected()));// color selector starts disabled until a channel is selectedui->colorSelector->setColor(QColor(0,0,0,0));ui->colorSelector->setDisplayMode(color_widgets::ColorPreview::AllAlpha);ui->colorSelector->setDisabled(true);// reset buttonresetMenu.addAction(&resetNamesAct);resetMenu.addAction(&resetColorsAct);resetMenu.addAction(&showAllAct);resetAct.setMenu(&resetMenu);ui->tbReset->setDefaultAction(&resetAct);}PlotControlPanel::~PlotControlPanel(){delete ui;}unsigned PlotControlPanel::numOfSamples(){return ui->spNumOfSamples->value();}void PlotControlPanel::onNumOfSamples(int value){if (warnNumOfSamples && value > NUMSAMPLES_CONFIRM_AT){// ask confirmationif (!askNSConfirmation(value)){// revert to old valuedisconnect(ui->spNumOfSamples, SIGNAL(valueChanged(int)),this, SLOT(onNumOfSamples(int)));ui->spNumOfSamples->setValue(_numOfSamples);connect(ui->spNumOfSamples, SIGNAL(valueChanged(int)),this, SLOT(onNumOfSamples(int)));return;}}_numOfSamples = value;emit numOfSamplesChanged(value);}bool PlotControlPanel::askNSConfirmation(int value){auto text = tr("Setting number of samples to a too big value ""(>%1) can seriously impact the performance of ""the application and cause freezes. Are you sure you ""want to change the number of samples to %2?").arg(QString::number(NUMSAMPLES_CONFIRM_AT), QString::number(value));// TODO: parent the mainwindowQMessageBox mb(QMessageBox::Warning,tr("Confirm Number of Samples"),text,QMessageBox::Apply | QMessageBox::Cancel,this);auto cb = new QCheckBox("Don't show this again.");connect(cb, &QCheckBox::stateChanged, [this](int state){warnNumOfSamples = (state == Qt::Unchecked);});mb.setCheckBox(cb);return mb.exec() == QMessageBox::Apply;}void PlotControlPanel::onAutoScaleChecked(bool checked){if (checked){ui->lYmin->setEnabled(false);ui->lYmax->setEnabled(false);ui->spYmin->setEnabled(false);ui->spYmax->setEnabled(false);emit yScaleChanged(true); // autoscale}else{ui->lYmin->setEnabled(true);ui->lYmax->setEnabled(true);ui->spYmin->setEnabled(true);ui->spYmax->setEnabled(true);emit yScaleChanged(false, ui->spYmin->value(), ui->spYmax->value());}}void PlotControlPanel::onYScaleChanged(){if (!autoScale()){emit yScaleChanged(false, ui->spYmin->value(), ui->spYmax->value());}}bool PlotControlPanel::autoScale() const{return ui->cbAutoScale->isChecked();}double PlotControlPanel::yMax() const{return ui->spYmax->value();}double PlotControlPanel::yMin() const{return ui->spYmin->value();}bool PlotControlPanel::xAxisAsIndex() const{return ui->cbIndex->isChecked();}double PlotControlPanel::xMax() const{return ui->spXmax->value();}double PlotControlPanel::xMin() const{return ui->spXmin->value();}void PlotControlPanel::onRangeSelected(){Range r = ui->cbRangePresets->currentData().value<Range>();ui->spYmin->setValue(r.rmin);ui->spYmax->setValue(r.rmax);ui->cbAutoScale->setChecked(false);}void PlotControlPanel::onIndexChecked(bool checked){if (checked){ui->lXmin->setEnabled(false);ui->lXmax->setEnabled(false);ui->spXmin->setEnabled(false);ui->spXmax->setEnabled(false);emit xScaleChanged(true); // use index}else{ui->lXmin->setEnabled(true);ui->lXmax->setEnabled(true);ui->spXmin->setEnabled(true);ui->spXmax->setEnabled(true);emit xScaleChanged(false, ui->spXmin->value(), ui->spXmax->value());}emit plotWidthChanged(plotWidth());}void PlotControlPanel::onXScaleChanged(){if (!xAxisAsIndex()){emit xScaleChanged(false, ui->spXmin->value(), ui->spXmax->value());emit plotWidthChanged(plotWidth());}}double PlotControlPanel::plotWidth() const{double value = ui->spPlotWidth->value();if (!xAxisAsIndex()){// scale by xmin and xmaxauto xmax = ui->spXmax->value();auto xmin = ui->spXmin->value();double scale = (xmax - xmin) / _numOfSamples;value *= scale;}return value;}void PlotControlPanel::onPlotWidthChanged(){emit plotWidthChanged(plotWidth());}void PlotControlPanel::setChannelInfoModel(ChannelInfoModel* model){ui->tvChannelInfo->setModel(model);// channel color selectorconnect(ui->tvChannelInfo->selectionModel(), &QItemSelectionModel::currentRowChanged,[this](const QModelIndex ¤t, const QModelIndex &previous){// TODO: duplicate with below lambdaQColor color(0,0,0,0); // transparentif (current.isValid()){ui->colorSelector->setEnabled(true);auto model = ui->tvChannelInfo->model();color = model->data(current, Qt::ForegroundRole).value<QColor>();}else{ui->colorSelector->setDisabled(true);}// temporarily block signals because `setColor` emits `colorChanged`bool wasBlocked = ui->colorSelector->blockSignals(true);ui->colorSelector->setColor(color);ui->colorSelector->blockSignals(wasBlocked);});connect(ui->tvChannelInfo->selectionModel(), &QItemSelectionModel::selectionChanged,[this](const QItemSelection & selected, const QItemSelection & deselected){if (!selected.length()){ui->colorSelector->setDisabled(true);// temporarily block signals because `setColor` emits `colorChanged`bool wasBlocked = ui->colorSelector->blockSignals(true);ui->colorSelector->setColor(QColor(0,0,0,0));ui->colorSelector->blockSignals(wasBlocked);}});connect(ui->colorSelector, &color_widgets::ColorSelector::colorChanged,[this](QColor color){auto index = ui->tvChannelInfo->selectionModel()->currentIndex();ui->tvChannelInfo->model()->setData(index, color, Qt::ForegroundRole);});connect(model, &QAbstractItemModel::dataChanged,[this](const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles = QVector<int> ()){auto current = ui->tvChannelInfo->selectionModel()->currentIndex();// no current selectionif (!current.isValid()) return;auto mod = ui->tvChannelInfo->model();QColor color = mod->data(current, Qt::ForegroundRole).value<QColor>();// temporarily block signals because `setColor` emits `colorChanged`bool wasBlocked = ui->colorSelector->blockSignals(true);ui->colorSelector->setColor(color);ui->colorSelector->blockSignals(wasBlocked);});// reset actionsconnect(&resetAct, &QAction::triggered, model, &ChannelInfoModel::resetInfos);connect(&resetNamesAct, &QAction::triggered, model, &ChannelInfoModel::resetNames);connect(&resetColorsAct, &QAction::triggered, model, &ChannelInfoModel::resetColors);connect(&showAllAct, &QAction::triggered, model, &ChannelInfoModel::resetVisibility);}void PlotControlPanel::saveSettings(QSettings* settings){settings->beginGroup(SettingGroup_Plot);settings->setValue(SG_Plot_NumOfSamples, numOfSamples());settings->setValue(SG_Plot_PlotWidth, ui->spPlotWidth->value());settings->setValue(SG_Plot_IndexAsX, xAxisAsIndex());settings->setValue(SG_Plot_XMax, xMax());settings->setValue(SG_Plot_XMin, xMin());settings->setValue(SG_Plot_AutoScale, autoScale());settings->setValue(SG_Plot_YMax, yMax());settings->setValue(SG_Plot_YMin, yMin());settings->endGroup();}void PlotControlPanel::loadSettings(QSettings* settings){settings->beginGroup(SettingGroup_Plot);ui->spNumOfSamples->setValue(settings->value(SG_Plot_NumOfSamples, numOfSamples()).toInt());ui->spPlotWidth->setValue(settings->value(SG_Plot_PlotWidth, ui->spPlotWidth->value()).toInt());ui->cbIndex->setChecked(settings->value(SG_Plot_IndexAsX, xAxisAsIndex()).toBool());ui->spXmax->setValue(settings->value(SG_Plot_XMax, xMax()).toDouble());ui->spXmin->setValue(settings->value(SG_Plot_XMin, xMin()).toDouble());ui->cbAutoScale->setChecked(settings->value(SG_Plot_AutoScale, autoScale()).toBool());ui->spYmax->setValue(settings->value(SG_Plot_YMax, yMax()).toDouble());ui->spYmin->setValue(settings->value(SG_Plot_YMin, yMin()).toDouble());settings->endGroup();}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。