# HG changeset patch # User Teemu Piippo # Date 1525953443 -10800 # Node ID c59dac18b06bb6ce7a1254423b1d2ef0f427b60a # Parent 4c134708be050bdf3a29701235e4ce20d844a7e2 added scaling vector editing into the subfile editing dialog diff -r 4c134708be05 -r c59dac18b06b src/dialogs/subfilereferenceeditor.cpp --- a/src/dialogs/subfilereferenceeditor.cpp Wed Apr 25 18:55:15 2018 +0300 +++ b/src/dialogs/subfilereferenceeditor.cpp Thu May 10 14:57:23 2018 +0300 @@ -49,7 +49,15 @@ { QLayoutItem* item = this->ui.matrixLayout->itemAtPosition(i, j); QDoubleSpinBox* spinbox = item ? qobject_cast(item->widget()) : nullptr; + spinbox->blockSignals(true); spinbox->setValue(reference->transformationMatrix()(i, j)); + spinbox->blockSignals(false); + connect( + spinbox, + qOverload(&QDoubleSpinBox::valueChanged), + this, + &SubfileReferenceEditor::matrixChanged + ); } connect( this->ui.primitivesTreeView, @@ -63,6 +71,69 @@ this->ui.referenceName->setText(primitiveName.toString()); } ); + + for (QDoubleSpinBox* spinbox : {this->ui.scalingX, this->ui.scalingY, this->ui.scalingZ}) + { + connect( + spinbox, + qOverload(&QDoubleSpinBox::valueChanged), + this, + &SubfileReferenceEditor::scalingChanged + ); + } + + // Fill in the initial scaling values + for (int column : {0, 1, 2}) + { + QDoubleSpinBox* spinbox = this->vectorElement(column); + spinbox->blockSignals(true); + spinbox->setValue(this->matrixScaling(column)); + spinbox->blockSignals(false); + } +} + +SubfileReferenceEditor::~SubfileReferenceEditor() +{ + delete &this->ui; +} + +/* + * Returns a spinbox from the matrix grid at position (row, column). + * Row and column must be within [0, 2]. + */ +QDoubleSpinBox* SubfileReferenceEditor::matrixCell(int row, int column) const +{ + if (qBound(0, row, 2) != row or qBound(0, column, 2) != column) + { + throw std::out_of_range {"bad row and column values"}; + } + else + { + QLayoutItem* item = this->ui.matrixLayout->itemAtPosition(row, column); + return item ? qobject_cast(item->widget()) : nullptr; + } +} + +/* + * Returns a spinbox for the vector element at the given position + * Index must be within [0, 2] + */ +QDoubleSpinBox* SubfileReferenceEditor::vectorElement(int index) +{ + switch (index) + { + case 0: + return this->ui.scalingX; + + case 1: + return this->ui.scalingY; + + case 2: + return this->ui.scalingZ; + + default: + throw std::out_of_range {"bad index"}; + } } void SubfileReferenceEditor::accept() @@ -72,9 +143,7 @@ for (int i : {0, 1, 2}) for (int j : {0, 1, 2}) { - QLayoutItem* item = this->ui.matrixLayout->itemAtPosition(i, j); - QDoubleSpinBox* spinbox = item ? qobject_cast(item->widget()) : nullptr; - transformationMatrix(i, j) = spinbox->value(); + transformationMatrix(i, j) = this->matrixCell(i, j)->value(); } this->reference->setTransformationMatrix(transformationMatrix); this->reference->setPosition({ @@ -91,7 +160,74 @@ this->ui.primitivesTreeView->setModel(primitives); } -SubfileReferenceEditor::~SubfileReferenceEditor() +double SubfileReferenceEditor::matrixScaling(int column) const +{ + return sqrt( + pow(this->matrixCell(0, column)->value(), 2) + + pow(this->matrixCell(1, column)->value(), 2) + + pow(this->matrixCell(2, column)->value(), 2) + ); +} + +/* + * Updates the appropriate matrix column when a scaling vector element is changed. + */ +void SubfileReferenceEditor::scalingChanged() { - delete &this->ui; + for (int column : {0, 1, 2}) + { + if (this->sender() == this->vectorElement(column)) + { + double oldScaling = this->matrixScaling(column); + double newScaling = static_cast(this->sender())->value(); + + if (not qFuzzyCompare(newScaling, 0.0)) + { + for (int row : {0, 1, 2}) + { + double cellValue = abs(this->matrixCell(row, column)->value()); + cellValue *= newScaling / oldScaling; + QDoubleSpinBox* cellWidget = this->matrixCell(row, column); + cellWidget->blockSignals(true); + cellWidget->setValue(cellValue); + cellWidget->blockSignals(false); + } + } + + break; + } + } } + +/* + * Finds the position for the given cell widget. + */ +QPair SubfileReferenceEditor::cellPosition(QDoubleSpinBox* cellWidget) +{ + for (int row : {0, 1, 2}) + for (int column : {0, 1, 2}) + { + if (this->matrixCell(row, column) == cellWidget) + return {row, column}; + } + + throw std::out_of_range {"widget is not in the matrix"}; +} + +/* + * Updates the appropriate scaling vector element when a matrix cell is changed. + */ +void SubfileReferenceEditor::matrixChanged() +{ + QDoubleSpinBox* cellWidget = static_cast(this->sender()); + + try + { + int column = this->cellPosition(cellWidget).second; + QDoubleSpinBox* spinbox = this->vectorElement(column); + spinbox->blockSignals(true); + spinbox->setValue(this->matrixScaling(column)); + spinbox->blockSignals(false); + } + catch (const std::out_of_range&) {} +} diff -r 4c134708be05 -r c59dac18b06b src/dialogs/subfilereferenceeditor.h --- a/src/dialogs/subfilereferenceeditor.h Wed Apr 25 18:55:15 2018 +0300 +++ b/src/dialogs/subfilereferenceeditor.h Thu May 10 14:57:23 2018 +0300 @@ -20,6 +20,8 @@ #include #include "../main.h" +class QDoubleSpinBox; + class SubfileReferenceEditor : public QDialog { Q_OBJECT @@ -31,7 +33,16 @@ void accept() override; void setPrimitivesTree(class PrimitiveManager* primitives); +private slots: + void scalingChanged(); + void matrixChanged(); + private: + QDoubleSpinBox* matrixCell(int row, int column) const; + double matrixScaling(int column) const; + QPair cellPosition(QDoubleSpinBox* cellWidget); + QDoubleSpinBox* vectorElement(int index); + class Ui_SubfileReferenceEditor& ui; class LDSubfileReference* const reference; LDColor color; diff -r 4c134708be05 -r c59dac18b06b src/dialogs/subfilereferenceeditor.ui --- a/src/dialogs/subfilereferenceeditor.ui Wed Apr 25 18:55:15 2018 +0300 +++ b/src/dialogs/subfilereferenceeditor.ui Thu May 10 14:57:23 2018 +0300 @@ -7,7 +7,7 @@ 0 0 625 - 642 + 644 @@ -110,6 +110,13 @@ + + + + Qt::Horizontal + + + @@ -238,8 +245,67 @@ - - + + + + Scaling vector: + + + + + + + + + 𝑥 × + + + 5 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 𝑦 × + + + 5 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + 𝑧 × + + + 5 + + + -10000.000000000000000 + + + 10000.000000000000000 + + + + + + + Qt::Horizontal @@ -259,6 +325,26 @@ + + primitivesTreeView + referenceName + colorButton + positionX + positionY + positionZ + matrixA + matrixB + matrixC + matrixD + matrixE + matrixF + matrixG + matrixH + matrixI + scalingX + scalingY + scalingZ + @@ -268,8 +354,8 @@ accept() - 248 - 254 + 257 + 634 157 @@ -284,8 +370,8 @@ reject() - 316 - 260 + 325 + 634 286