From ecb62257c2d35344bae6991d512b8c99056c6ec4 Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Sat, 3 Oct 2020 07:34:25 +0300 Subject: [PATCH] Dimension controls. --- src/app/tape/tmainwindow.cpp | 388 ++++++++++++++++++++++++----- src/app/tape/tmainwindow.h | 21 +- src/libs/vformat/vmeasurements.cpp | 12 + src/libs/vformat/vmeasurements.h | 3 + 4 files changed, 350 insertions(+), 74 deletions(-) diff --git a/src/app/tape/tmainwindow.cpp b/src/app/tape/tmainwindow.cpp index 115ced42a..7ebaeda13 100644 --- a/src/app/tape/tmainwindow.cpp +++ b/src/app/tape/tmainwindow.cpp @@ -64,6 +64,7 @@ #include #include #include +#include #if defined(Q_OS_MAC) #include @@ -87,7 +88,8 @@ enum {ColumnName = 0, ColumnFullName, ColumnCalcValue, ColumnFormula, ColumnBase TMainWindow::TMainWindow(QWidget *parent) : VAbstractMainWindow(parent), ui(new Ui::TMainWindow), - formulaBaseHeight(0) + formulaBaseHeight(0), + gradation(new QTimer(this)) { ui->setupUi(this); @@ -110,6 +112,8 @@ TMainWindow::TMainWindow(QWidget *parent) m_recentFileActs.fill(nullptr); + connect(gradation, &QTimer::timeout, this, &TMainWindow::GradationChanged); + SetupMenu(); UpdateWindowTitle(); ReadSettings(); @@ -401,6 +405,8 @@ void TMainWindow::FileNew() m->SetFullCircumference(setup.FullCircumference()); m_curFileFormatVersion = VVSTConverter::MeasurementMaxVer; m_curFileFormatVersionStr = VVSTConverter::MeasurementMaxVerStr; + + SetCurrentDimensionValues(); } else { @@ -583,9 +589,7 @@ void TMainWindow::changeEvent(QEvent *event) ui->labelMType->setText(tr("Multisize measurements")); InitDimensionsBaseValue(); - - labelGradationHeights->setText(tr("Height (%1):").arg(UnitsToStr(mUnit))); - labelGradationSizes->setText(tr("Size (%1):").arg(UnitsToStr(mUnit))); + InitDimensionControls(); } else { @@ -609,7 +613,7 @@ void TMainWindow::changeEvent(QEvent *event) } { - labelPatternUnit = new QLabel(tr("Pattern unit:")); + labelPatternUnit->setText(tr("Pattern unit:")); if (comboBoxUnits != nullptr) { @@ -1476,20 +1480,54 @@ void TMainWindow::ImportFromPattern() } //--------------------------------------------------------------------------------------------------------------------- -void TMainWindow::ChangedSize(const QString &text) +void TMainWindow::DimensionABaseChanged() { - const int row = ui->tableWidget->currentRow(); - currentDimensionB = text.toInt(); - RefreshData(); - search->RefreshList(ui->lineEditFind->text()); - ui->tableWidget->selectRow(row); + currentDimensionA = gradationDimensionA->currentData().toInt(); + + const QList dimensions = m->Dimensions().values(); + if (dimensions.size() > 1) + { + MeasurementDimension_p dimension = dimensions.at(1); + InitDimensionGradation(1, dimension, gradationDimensionB); + + if (dimensions.size() > 2) + { + dimension = dimensions.at(2); + InitDimensionGradation(2, dimension, gradationDimensionC); + } + } + + gradation->start(); } //--------------------------------------------------------------------------------------------------------------------- -void TMainWindow::ChangedHeight(const QString &text) +void TMainWindow::DimensionBBaseChanged() { + currentDimensionB = gradationDimensionB->currentData().toInt(); + + const QList dimensions = m->Dimensions().values(); + + if (dimensions.size() > 2) + { + MeasurementDimension_p dimension = dimensions.at(2); + InitDimensionGradation(2, dimension, gradationDimensionC); + } + + gradation->start(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TMainWindow::DimensionCBaseChanged() +{ + currentDimensionC = gradationDimensionC->currentData().toInt(); + gradation->start(); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TMainWindow::GradationChanged() +{ + gradation->stop(); const int row = ui->tableWidget->currentRow(); - currentDimensionA = text.toInt(); RefreshData(); search->RefreshList(ui->lineEditFind->text()); ui->tableWidget->selectRow(row); @@ -1940,6 +1978,7 @@ void TMainWindow::FullCircumferenceChanged(bool checked) m->SetFullCircumference(checked); MeasurementsWereSaved(false); InitDimensionsBaseValue(); + InitDimensionControls(); } //--------------------------------------------------------------------------------------------------------------------- @@ -2074,20 +2113,9 @@ void TMainWindow::InitWindow() HackWidget(&ui->labelGender); HackWidget(&ui->labelEmail); - const QStringList listHeights = VMeasurement::WholeListHeights(mUnit); - const QStringList listSizes = VMeasurement::WholeListSizes(mUnit); - - labelGradationHeights = new QLabel(tr("Height (%1):").arg(UnitsToStr(mUnit))); - gradationHeights = SetGradationList(labelGradationHeights, listHeights); - SetDefaultHeight(static_cast(data->height())); - connect(gradationHeights, &QComboBox::currentTextChanged, - this, &TMainWindow::ChangedHeight); - - labelGradationSizes = new QLabel(tr("Size (%1):").arg(UnitsToStr(mUnit))); - gradationSizes = SetGradationList(labelGradationSizes, listSizes); - SetDefaultSize(static_cast(data->size())); - connect(gradationSizes, &QComboBox::currentTextChanged, - this, &TMainWindow::ChangedSize); + InitDimensionControls(); + ShowDimensionControls(); + SetDimensionBases(); connect(ui->doubleSpinBoxBaseValue, QOverload::of(&QDoubleSpinBox::valueChanged), this, &TMainWindow::SaveMBaseValue); @@ -2259,6 +2287,107 @@ void TMainWindow::InitDimensionsBaseValue() DimensionsBaseValue(2, ui->labelDimensionC, ui->labelDimensionCBase); } +//--------------------------------------------------------------------------------------------------------------------- +void TMainWindow::InitDimensionGradation(int index, const MeasurementDimension_p &dimension, QComboBox *control) +{ + SCASSERT(control != nullptr) + + const bool fc = m->IsFullCircumference(); + const QString unit = UnitsToStr(m->MUnit(), true); + + int current = -1; + if (control->currentIndex() != -1) + { + current = control->currentData().toInt(); + } + + control->blockSignals(true); + control->clear(); + + if (dimension->Type() == MeasurementDimension::X) + { + const QVector bases = DimensionRestrictedValues(index, dimension); + + for(auto base : bases) + { + control->addItem(QString("%1 %2").arg(base).arg(unit), base); + } + } + else if (dimension->Type() == MeasurementDimension::Y) + { + const QVector bases = dimension->ValidBases(); + + for(auto base : bases) + { + if (dimension->IsCircumference()) + { + control->addItem(QString("%1 %2").arg(fc ? base*2 : base).arg(unit), base); + } + else + { + control->addItem(QString::number(base), base); + } + } + } + else if (dimension->Type() == MeasurementDimension::W || dimension->Type() == MeasurementDimension::Z) + { + const QVector bases = dimension->ValidBases(); + + for(auto base : bases) + { + control->addItem(QString("%1 %2").arg(fc ? base*2 : base).arg(unit), base); + } + } + + int i = control->findData(current); + if (i != -1) + { + control->setCurrentIndex(i); + control->blockSignals(false); + } + else + { + control->blockSignals(false); + control->setCurrentIndex(0); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void TMainWindow::InitDimensionControls() +{ + const QList dimensions = m->Dimensions().values(); + const QString unit = UnitsToStr(m->MUnit(), true); + + auto InitControl = [this, dimensions, unit](int index, QLabel *&name, QComboBox *&control) + { + if (dimensions.size() > index) + { + MeasurementDimension_p dimension = dimensions.at(index); + + if (name == nullptr) + { + name = new QLabel(DimensionName(dimension->Type())+QChar(':')); + } + else + { + name->setText(DimensionName(dimension->Type())+QChar(':')); + } + name->setToolTip(DimensionToolTip(dimension->Type(), dimension->IsCircumference())); + + if (control == nullptr) + { + control = new QComboBox; + } + + InitDimensionGradation(index, dimension, control); + } + }; + + InitControl(0, labelGradationDimensionA, gradationDimensionA); + InitControl(1, labelGradationDimensionB, gradationDimensionB); + InitControl(2, labelGradationDimensionC, gradationDimensionC); +} + //--------------------------------------------------------------------------------------------------------------------- void TMainWindow::InitTable() { @@ -2431,46 +2560,6 @@ QTableWidgetItem *TMainWindow::AddCell(const QString &text, int row, int column, return item; } -//--------------------------------------------------------------------------------------------------------------------- -QComboBox *TMainWindow::SetGradationList(QLabel *label, const QStringList &list) -{ - ui->toolBarGradation->addWidget(label); - - auto *comboBox = new QComboBox; - comboBox->addItems(list); - ui->toolBarGradation->addWidget(comboBox); - - return comboBox; -} - -//--------------------------------------------------------------------------------------------------------------------- -void TMainWindow::SetDefaultHeight(int value) -{ - const qint32 index = gradationHeights->findText(QString::number(value)); - if (index != -1) - { - gradationHeights->setCurrentIndex(index); - } - else - { - currentDimensionA = gradationHeights->currentText().toInt(); - } -} - -//--------------------------------------------------------------------------------------------------------------------- -void TMainWindow::SetDefaultSize(int value) -{ - const qint32 index = gradationSizes->findText(QString::number(value)); - if (index != -1) - { - gradationSizes->setCurrentIndex(index); - } - else - { - currentDimensionB = gradationSizes->currentText().toInt(); - } -} - //--------------------------------------------------------------------------------------------------------------------- void TMainWindow::RefreshData(bool freshCall) { @@ -3453,6 +3542,171 @@ QString TMainWindow::DimensionToolTip(MeasurementDimension type, bool circumfere } } +//--------------------------------------------------------------------------------------------------------------------- +void TMainWindow::ShowDimensionControls() +{ + const QList dimensions = m->Dimensions().values(); + + auto ShowControl = [this, dimensions](int index, QLabel *name, QComboBox *control) + { + if (dimensions.size() > index) + { + SCASSERT(name != nullptr) + SCASSERT(control != nullptr) + + ui->toolBarGradation->addWidget(name); + ui->toolBarGradation->addWidget(control); + } + }; + + ShowControl(0, labelGradationDimensionA, gradationDimensionA); + ShowControl(1, labelGradationDimensionB, gradationDimensionB); + ShowControl(2, labelGradationDimensionC, gradationDimensionC); + + if (gradationDimensionA) + { + connect(gradationDimensionA, QOverload::of(&QComboBox::currentIndexChanged), + this, &TMainWindow::DimensionABaseChanged); + } + + if (gradationDimensionB) + { + connect(gradationDimensionB, QOverload::of(&QComboBox::currentIndexChanged), + this, &TMainWindow::DimensionBBaseChanged); + } + + if (gradationDimensionC) + { + connect(gradationDimensionC, QOverload::of(&QComboBox::currentIndexChanged), + this, &TMainWindow::DimensionCBaseChanged); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void TMainWindow::SetDimensionBases() +{ + const QList dimensions = m->Dimensions().values(); + + auto SetBase = [dimensions](int index, QComboBox *control, int &value) + { + if (dimensions.size() > index) + { + SCASSERT(control != nullptr) + + MeasurementDimension_p dimension = dimensions.at(index); + + const qint32 i = control->findData(value); + if (i != -1) + { + control->setCurrentIndex(i); + } + else + { + value = control->currentData().toInt(); + } + } + }; + + SetBase(0, gradationDimensionA, currentDimensionA); + SetBase(1, gradationDimensionB, currentDimensionB); + SetBase(2, gradationDimensionC, currentDimensionC); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TMainWindow::SetCurrentDimensionValues() +{ + const QList dimensions = m->Dimensions().values(); + + auto SetDimensionValue = [dimensions](int index, int &value) + { + if (dimensions.size() > index) + { + MeasurementDimension_p dimension = dimensions.at(index); + value = dimension->BaseValue(); + } + }; + + SetDimensionValue(0, currentDimensionA); + SetDimensionValue(1, currentDimensionB); + SetDimensionValue(2, currentDimensionC); +} + +//--------------------------------------------------------------------------------------------------------------------- +QVector TMainWindow::DimensionRestrictedValues(int index, const MeasurementDimension_p &dimension) +{ + if (index == 0) + { + return dimension->ValidBases(); + } + + if (dimension->Type() == MeasurementDimension::X) + { + return dimension->ValidBases(); + } + else if (dimension->Type() == MeasurementDimension::Y) + { + const QPair restriction = m->OneDimensionRestriction(currentDimensionA); + VYMeasurementDimension restricted(dimension->Units(), restriction.first, restriction.second, dimension->Step()); + restricted.SetCircumference(dimension->IsCircumference()); + + if (restriction.first < dimension->MinValue() || restriction.second > dimension->MaxValue() + || not restricted.IsValid()) + { // invalid restriction + return dimension->ValidBases(); + } + + return restricted.ValidBases(); + } + else if (dimension->Type() == MeasurementDimension::W) + { + QPair restriction; + + if (index == 1) + { + restriction = m->OneDimensionRestriction(currentDimensionA); + } + else + { + restriction = m->TwoDimensionRestriction(currentDimensionA, currentDimensionB); + } + + VWMeasurementDimension restricted(dimension->Units(), restriction.first, restriction.second, dimension->Step()); + + if (restriction.first < dimension->MinValue() || restriction.second > dimension->MaxValue() + || not restricted.IsValid()) + { // invalid restriction + return dimension->ValidBases(); + } + + return restricted.ValidBases(); + } + else if (dimension->Type() == MeasurementDimension::Z) + { + QPair restriction; + + if (index == 1) + { + restriction = m->OneDimensionRestriction(currentDimensionA); + } + else + { + restriction = m->TwoDimensionRestriction(currentDimensionA, currentDimensionB); + } + + VZMeasurementDimension restricted(dimension->Units(), restriction.first, restriction.second, dimension->Step()); + + if (restriction.first < dimension->MinValue() || restriction.second > dimension->MaxValue() + || not restricted.IsValid()) + { // invalid restriction + return dimension->ValidBases(); + } + + return restricted.ValidBases(); + } + + return QVector(); +} + //--------------------------------------------------------------------------------------------------------------------- void TMainWindow::SetDecimals() { diff --git a/src/app/tape/tmainwindow.h b/src/app/tape/tmainwindow.h index e115f7a75..d500a86a2 100644 --- a/src/app/tape/tmainwindow.h +++ b/src/app/tape/tmainwindow.h @@ -113,8 +113,11 @@ private slots: void AddKnown(); void ImportFromPattern(); - void ChangedSize(const QString &text); - void ChangedHeight(const QString & text); + void DimensionABaseChanged(); + void DimensionBBaseChanged(); + void DimensionCBaseChanged(); + + void GradationChanged(); void ShowMData(); @@ -156,6 +159,7 @@ private: bool isInitialized{false}; bool mIsReadOnly{false}; QAction *actionFullCircumference{nullptr}; + QTimer *gradation; QVector hackedWidgets{}; @@ -163,6 +167,8 @@ private: void InitWindow(); void InitMenu(); void InitDimensionsBaseValue(); + void InitDimensionGradation(int index, const MeasurementDimension_p &dimension, QComboBox *control); + void InitDimensionControls(); void InitTable(); void SetDecimals(); void InitUnits(); @@ -181,11 +187,6 @@ private: QTableWidgetItem *AddCell(const QString &text, int row, int column, int aligment, bool ok = true); - Q_REQUIRED_RESULT QComboBox *SetGradationList(QLabel *label, const QStringList &list); - - void SetDefaultHeight(int value); - void SetDefaultSize(int value); - void RefreshData(bool freshCall = false); void RefreshTable(bool freshCall = false); @@ -230,6 +231,12 @@ private: QString DimensionName(MeasurementDimension type); QString DimensionToolTip(MeasurementDimension type, bool circumference); + + void ShowDimensionControls(); + void SetDimensionBases(); + void SetCurrentDimensionValues(); + + QVector DimensionRestrictedValues(int index, const MeasurementDimension_p &dimension); }; #endif // TMAINWINDOW_H diff --git a/src/libs/vformat/vmeasurements.cpp b/src/libs/vformat/vmeasurements.cpp index 7301e3279..456b9bdef 100644 --- a/src/libs/vformat/vmeasurements.cpp +++ b/src/libs/vformat/vmeasurements.cpp @@ -684,6 +684,18 @@ QMap VMeasurements::Dimensions() return dimesions; } +//--------------------------------------------------------------------------------------------------------------------- +QPair VMeasurements::OneDimensionRestriction(int base) const +{ + return QPair(0, 0); +} + +//--------------------------------------------------------------------------------------------------------------------- +QPair VMeasurements::TwoDimensionRestriction(int base1, int base2) const +{ + return QPair(0, 0); +} + //--------------------------------------------------------------------------------------------------------------------- QString VMeasurements::GenderToStr(const GenderType &sex) { diff --git a/src/libs/vformat/vmeasurements.h b/src/libs/vformat/vmeasurements.h index 810d347a9..a3797a32a 100644 --- a/src/libs/vformat/vmeasurements.h +++ b/src/libs/vformat/vmeasurements.h @@ -109,6 +109,9 @@ public: QMap Dimensions() const; + QPair OneDimensionRestriction(int base) const; + QPair TwoDimensionRestriction(int base1, int base2) const; + static const QString TagVST; static const QString TagVIT; static const QString TagBodyMeasurements;