/* * Copyright (C) EdgeTX * * Based on code named * opentx - https://github.com/opentx/opentx * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 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. */ #include "mixerdialog.h" #include "ui_mixerdialog.h" #include "radiodata.h" #include "filtereditemmodels.h" #include "helpers.h" #include "namevalidator.h" #include "sourcenumref.h" MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, int index, GeneralSettings & generalSettings, Firmware * firmware, CompoundItemModelFactory * sharedItemModels) : QDialog(parent), ui(new Ui::MixerDialog), model(model), generalSettings(generalSettings), firmware(firmware), md(mixdata), lock(false) { ui->setupUi(this); Board::Type board = firmware->getBoard(); dialogFilteredItemModels = new FilteredItemModelFactory(); QLabel * lb_fp[CPN_MAX_FLIGHT_MODES] = {ui->lb_FP0, ui->lb_FP1, ui->lb_FP2, ui->lb_FP3, ui->lb_FP4, ui->lb_FP5, ui->lb_FP6, ui->lb_FP7, ui->lb_FP8 }; QCheckBox * tmp[CPN_MAX_FLIGHT_MODES] = {ui->cb_FP0, ui->cb_FP1, ui->cb_FP2, ui->cb_FP3, ui->cb_FP4, ui->cb_FP5, ui->cb_FP6, ui->cb_FP7, ui->cb_FP8 }; for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { cb_fp[i] = tmp[i]; } this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh).toString(&model, &generalSettings))); int imId = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), (RawSource::InputSourceGroups & ~RawSource::NoneGroup) | RawSource::ScriptsGroup), "RawSource"); ui->sourceCB->setSizeAdjustPolicy(QComboBox::AdjustToContents); ui->sourceCB->setModel(dialogFilteredItemModels->getItemModel(imId)); ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue())); if (ui->sourceCB->currentIndex() < 0 && md->srcRaw.toValue() == 0) ui->sourceCB->setCurrentIndex(Helpers::getFirstPosValueIndex(ui->sourceCB)); int limit = firmware->getCapability(OffsetWeight); imId = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSource), (RawSource::AllSourceGroups & ~RawSource::NoneGroup & ~RawSource::ScriptsGroup)), "EditorSource"); FilteredItemModel *esMdl = dialogFilteredItemModels->getItemModel(imId); weightEditor = new SourceNumRefEditor(md->weight, ui->chkWeightUseSource, ui->sbWeightValue, ui->cboWeightSource, 100, -limit, limit, 1, model, esMdl, this); connect(weightEditor, &SourceNumRefEditor::resized, this, [=] () { shrink(); }); offsetEditor = new SourceNumRefEditor(md->sOffset, ui->chkOffsetUseSource, ui->sbOffsetValue, ui->cboOffsetSource, 0, -limit, limit, 1, model, esMdl, this); connect(offsetEditor, &SourceNumRefEditor::resized, this, [=] () { shrink(); }); curveRefFilteredItemModels = new CurveRefFilteredFactory(sharedItemModels, firmware->getCapability(HasMixerExpo) ? 0 : FilteredItemModel::PositiveFilter); curveGroup = new CurveReferenceUIManager(ui->cboCurveType, ui->chkCurveUseSource, ui->sbCurveValue, ui->cboCurveSource, ui->cboCurveFunc, ui->imgCurve, md->curve, model, sharedItemModels, curveRefFilteredItemModels, esMdl, this); connect(curveGroup, &CurveReferenceUIManager::resized, this, [=] () { shrink(); }); ui->MixDR_CB->setChecked(md->noExpo == 0); if (!firmware->getCapability(HasNoExpo)) { ui->MixDR_CB->hide(); ui->label_MixDR->hide(); } if (index == 0 || model.mixData[index - 1].destCh != mixdata->destCh) { ui->mltpxCB->hide(); ui->mltpxLbl->hide(); } if (!firmware->getCapability(VirtualInputs)) { for(int i = 0; i < CPN_MAX_STICKS; i++) { ui->trimCB->addItem(Boards::getInputName(i, board)); } } ui->trimCB->setCurrentIndex(1 - md->carryTrim); int namelength = firmware->getCapability(HasMixerNames); if (!namelength) { ui->label_name->hide(); ui->mixerName->hide(); } else { ui->mixerName->setMaxLength(namelength); } ui->mixerName->setValidator(new NameValidator(board, this)); ui->mixerName->setText(md->name); if (!firmware->getCapability(FlightModes)) { ui->label_phases->hide(); for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { lb_fp[i]->hide(); cb_fp[i]->hide(); } } else { ui->label_phases->setToolTip(tr("Click to access popup menu")); ui->label_phases->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->label_phases, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(label_phases_customContextMenuRequested(const QPoint &))); int mask = 1; for (int i = 0; i < CPN_MAX_FLIGHT_MODES ; i++) { if ((md->flightModes & mask) == 0) { cb_fp[i]->setChecked(true); } mask <<= 1; } for (int i = firmware->getCapability(FlightModes); i < CPN_MAX_FLIGHT_MODES; i++) { lb_fp[i]->hide(); cb_fp[i]->hide(); } } imId = dialogFilteredItemModels->registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_RawSwitch), RawSwitch::MixesContext), "RawSwitch"); ui->switchesCB->setSizeAdjustPolicy(QComboBox::AdjustToContents); ui->switchesCB->setModel(dialogFilteredItemModels->getItemModel(imId)); ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue())); ui->warningCB->setCurrentIndex(md->mixWarn); ui->mltpxCB->setCurrentIndex(md->mltpx); ui->delayPrecCB->setCurrentIndex(md->delayPrec); ui->speedPrecCB->setCurrentIndex(md->speedPrec); float range = firmware->getCapability(SlowRange); int scale = firmware->getCapability(SlowScale); if (md->delayPrec) scale = scale * 10; ui->delayDownSB->setMaximum(range / scale); ui->delayDownSB->setSingleStep(1.0 / scale); ui->delayDownSB->setDecimals((scale == 1 ? 0 : scale == 10 ? 1 : 2)); ui->delayDownSB->setValue((float)md->delayDown / scale); ui->delayUpSB->setMaximum(range / scale); ui->delayUpSB->setSingleStep(1.0 / scale); ui->delayUpSB->setDecimals((scale == 1 ? 0 : scale == 10 ? 1 : 2)); ui->delayUpSB->setValue((float)md->delayUp / scale); scale = firmware->getCapability(SlowScale); if (md->speedPrec) scale = scale * 10; ui->slowDownSB->setMaximum(range / scale); ui->slowDownSB->setSingleStep(1.0 / scale); ui->slowDownSB->setDecimals((scale == 1 ? 0 : scale == 10 ? 1 : 2)); ui->slowDownSB->setValue((float)md->speedDown/scale); ui->slowUpSB->setMaximum(range / scale); ui->slowUpSB->setSingleStep(1.0 / scale); ui->slowUpSB->setDecimals((scale == 1 ? 0 : scale == 10 ? 1 : 2)); ui->slowUpSB->setValue((float)md->speedUp/scale); valuesChanged(); connect(ui->mixerName, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); connect(ui->sourceCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->trimCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->MixDR_CB, SIGNAL(toggled(bool)), this, SLOT(valuesChanged())); connect(ui->switchesCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->warningCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->mltpxCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->delayPrecCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->delayDownSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); connect(ui->delayUpSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); connect(ui->speedPrecCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged())); connect(ui->slowDownSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); connect(ui->slowUpSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged())); for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { connect(cb_fp[i], SIGNAL(toggled(bool)), this, SLOT(valuesChanged())); } shrink(); } MixerDialog::~MixerDialog() { delete ui; delete weightEditor; delete offsetEditor; delete dialogFilteredItemModels; delete curveRefFilteredItemModels; } void MixerDialog::changeEvent(QEvent *e) { QDialog::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } void MixerDialog::valuesChanged() { if (!lock) { lock = true; md->srcRaw = RawSource(ui->sourceCB->itemData(ui->sourceCB->currentIndex()).toInt()); if (firmware->getCapability(HasNoExpo)) { bool drVisible = (md->srcRaw.type == SOURCE_TYPE_INPUT && md->srcRaw.index < CPN_MAX_STICKS); ui->MixDR_CB->setEnabled(drVisible); ui->label_MixDR->setEnabled(drVisible); } md->carryTrim = -(ui->trimCB->currentIndex() - 1); md->noExpo = ui->MixDR_CB->checkState() ? 0 : 1; md->swtch = RawSwitch(ui->switchesCB->itemData(ui->switchesCB->currentIndex()).toInt()); md->mixWarn = ui->warningCB->currentIndex(); md->mltpx = (MltpxValue)ui->mltpxCB->currentIndex(); float range = firmware->getCapability(SlowRange); // Update values based on old precision (in case it changed) int scale = firmware->getCapability(SlowScale); if (md->delayPrec) scale = scale * 10; md->delayDown = round(ui->delayDownSB->value() * scale); md->delayUp = round(ui->delayUpSB->value() * scale); // Get new precion and update controls md->delayPrec = ui->delayPrecCB->currentIndex(); scale = firmware->getCapability(SlowScale); if (md->delayPrec) scale = scale * 10; ui->delayDownSB->setMaximum(range / scale); ui->delayDownSB->setSingleStep(1.0 / scale); ui->delayDownSB->setDecimals((scale == 1 ? 0 : scale == 10 ? 1 : 2)); ui->delayDownSB->setValue((float)md->delayDown / scale); ui->delayUpSB->setMaximum(range / scale); ui->delayUpSB->setSingleStep(1.0 / scale); ui->delayUpSB->setDecimals((scale == 1 ? 0 : scale == 10 ? 1 : 2)); ui->delayUpSB->setValue((float)md->delayUp / scale); // Update values based on old precision (in case it changed) scale = firmware->getCapability(SlowScale); if (md->speedPrec) scale = scale * 10; md->speedDown = round(ui->slowDownSB->value() * scale); md->speedUp = round(ui->slowUpSB->value() * scale); // Get new precion and update controls md->speedPrec = ui->speedPrecCB->currentIndex(); scale = firmware->getCapability(SlowScale); if (md->speedPrec) scale = scale * 10; ui->slowDownSB->setMaximum(range / scale); ui->slowDownSB->setSingleStep(1.0 / scale); ui->slowDownSB->setDecimals((scale == 1 ? 0 : scale == 10 ? 1 : 2)); ui->slowDownSB->setValue((float)md->speedDown / scale); ui->slowUpSB->setMaximum(range / scale); ui->slowUpSB->setSingleStep(1.0 / scale); ui->slowUpSB->setDecimals((scale == 1 ? 0 : scale == 10 ? 1 : 2)); ui->slowUpSB->setValue((float)md->speedUp / scale); strcpy(md->name, ui->mixerName->text().toLatin1()); md->flightModes = 0; for (int i = CPN_MAX_FLIGHT_MODES - 1; i >= 0 ; i--) { if (!cb_fp[i]->checkState()) { md->flightModes++; } md->flightModes <<= 1; } md->flightModes >>= 1; lock = false; } } void MixerDialog::label_phases_customContextMenuRequested(const QPoint & pos) { QLabel *label = (QLabel *)sender(); QPoint globalPos = label->mapToGlobal(pos); QMenu contextMenu; contextMenu.addAction(tr("Clear All"), this, SLOT(fmClearAll())); contextMenu.addAction(tr("Set All"), this, SLOT(fmSetAll())); contextMenu.addAction(tr("Invert All"), this, SLOT(fmInvertAll())); contextMenu.exec(globalPos); } void MixerDialog::fmClearAll() { lock = true; for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { cb_fp[i]->setChecked(false); } lock = false; valuesChanged(); } void MixerDialog::fmSetAll() { lock = true; for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { cb_fp[i]->setChecked(true); } lock = false; valuesChanged(); } void MixerDialog::fmInvertAll() { lock = true; for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { cb_fp[i]->setChecked(!cb_fp[i]->isChecked()); } lock = false; valuesChanged(); } void MixerDialog::shrink() { this->adjustSize(); this->resize(0, 0); }