src/dialogs/subfilereferenceeditor.cpp

changeset 1386
c59dac18b06b
parent 1326
69a90bd2dba2
child 1387
6393b6020c62
equal deleted inserted replaced
1384:4c134708be05 1386:c59dac18b06b
47 for (int i : {0, 1, 2}) 47 for (int i : {0, 1, 2})
48 for (int j : {0, 1, 2}) 48 for (int j : {0, 1, 2})
49 { 49 {
50 QLayoutItem* item = this->ui.matrixLayout->itemAtPosition(i, j); 50 QLayoutItem* item = this->ui.matrixLayout->itemAtPosition(i, j);
51 QDoubleSpinBox* spinbox = item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : nullptr; 51 QDoubleSpinBox* spinbox = item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : nullptr;
52 spinbox->blockSignals(true);
52 spinbox->setValue(reference->transformationMatrix()(i, j)); 53 spinbox->setValue(reference->transformationMatrix()(i, j));
54 spinbox->blockSignals(false);
55 connect(
56 spinbox,
57 qOverload<double>(&QDoubleSpinBox::valueChanged),
58 this,
59 &SubfileReferenceEditor::matrixChanged
60 );
53 } 61 }
54 connect( 62 connect(
55 this->ui.primitivesTreeView, 63 this->ui.primitivesTreeView,
56 &QTreeView::clicked, 64 &QTreeView::clicked,
57 [&](const QModelIndex& index) 65 [&](const QModelIndex& index)
61 69
62 if (primitiveName.isValid()) 70 if (primitiveName.isValid())
63 this->ui.referenceName->setText(primitiveName.toString()); 71 this->ui.referenceName->setText(primitiveName.toString());
64 } 72 }
65 ); 73 );
74
75 for (QDoubleSpinBox* spinbox : {this->ui.scalingX, this->ui.scalingY, this->ui.scalingZ})
76 {
77 connect(
78 spinbox,
79 qOverload<double>(&QDoubleSpinBox::valueChanged),
80 this,
81 &SubfileReferenceEditor::scalingChanged
82 );
83 }
84
85 // Fill in the initial scaling values
86 for (int column : {0, 1, 2})
87 {
88 QDoubleSpinBox* spinbox = this->vectorElement(column);
89 spinbox->blockSignals(true);
90 spinbox->setValue(this->matrixScaling(column));
91 spinbox->blockSignals(false);
92 }
93 }
94
95 SubfileReferenceEditor::~SubfileReferenceEditor()
96 {
97 delete &this->ui;
98 }
99
100 /*
101 * Returns a spinbox from the matrix grid at position (row, column).
102 * Row and column must be within [0, 2].
103 */
104 QDoubleSpinBox* SubfileReferenceEditor::matrixCell(int row, int column) const
105 {
106 if (qBound(0, row, 2) != row or qBound(0, column, 2) != column)
107 {
108 throw std::out_of_range {"bad row and column values"};
109 }
110 else
111 {
112 QLayoutItem* item = this->ui.matrixLayout->itemAtPosition(row, column);
113 return item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : nullptr;
114 }
115 }
116
117 /*
118 * Returns a spinbox for the vector element at the given position
119 * Index must be within [0, 2]
120 */
121 QDoubleSpinBox* SubfileReferenceEditor::vectorElement(int index)
122 {
123 switch (index)
124 {
125 case 0:
126 return this->ui.scalingX;
127
128 case 1:
129 return this->ui.scalingY;
130
131 case 2:
132 return this->ui.scalingZ;
133
134 default:
135 throw std::out_of_range {"bad index"};
136 }
66 } 137 }
67 138
68 void SubfileReferenceEditor::accept() 139 void SubfileReferenceEditor::accept()
69 { 140 {
70 this->reference->setReferenceName(this->ui.referenceName->text()); 141 this->reference->setReferenceName(this->ui.referenceName->text());
71 Matrix transformationMatrix; 142 Matrix transformationMatrix;
72 for (int i : {0, 1, 2}) 143 for (int i : {0, 1, 2})
73 for (int j : {0, 1, 2}) 144 for (int j : {0, 1, 2})
74 { 145 {
75 QLayoutItem* item = this->ui.matrixLayout->itemAtPosition(i, j); 146 transformationMatrix(i, j) = this->matrixCell(i, j)->value();
76 QDoubleSpinBox* spinbox = item ? qobject_cast<QDoubleSpinBox*>(item->widget()) : nullptr;
77 transformationMatrix(i, j) = spinbox->value();
78 } 147 }
79 this->reference->setTransformationMatrix(transformationMatrix); 148 this->reference->setTransformationMatrix(transformationMatrix);
80 this->reference->setPosition({ 149 this->reference->setPosition({
81 this->ui.positionX->value(), 150 this->ui.positionX->value(),
82 this->ui.positionY->value(), 151 this->ui.positionY->value(),
89 void SubfileReferenceEditor::setPrimitivesTree(PrimitiveManager* primitives) 158 void SubfileReferenceEditor::setPrimitivesTree(PrimitiveManager* primitives)
90 { 159 {
91 this->ui.primitivesTreeView->setModel(primitives); 160 this->ui.primitivesTreeView->setModel(primitives);
92 } 161 }
93 162
94 SubfileReferenceEditor::~SubfileReferenceEditor() 163 double SubfileReferenceEditor::matrixScaling(int column) const
95 { 164 {
96 delete &this->ui; 165 return sqrt(
97 } 166 pow(this->matrixCell(0, column)->value(), 2) +
167 pow(this->matrixCell(1, column)->value(), 2) +
168 pow(this->matrixCell(2, column)->value(), 2)
169 );
170 }
171
172 /*
173 * Updates the appropriate matrix column when a scaling vector element is changed.
174 */
175 void SubfileReferenceEditor::scalingChanged()
176 {
177 for (int column : {0, 1, 2})
178 {
179 if (this->sender() == this->vectorElement(column))
180 {
181 double oldScaling = this->matrixScaling(column);
182 double newScaling = static_cast<QDoubleSpinBox*>(this->sender())->value();
183
184 if (not qFuzzyCompare(newScaling, 0.0))
185 {
186 for (int row : {0, 1, 2})
187 {
188 double cellValue = abs(this->matrixCell(row, column)->value());
189 cellValue *= newScaling / oldScaling;
190 QDoubleSpinBox* cellWidget = this->matrixCell(row, column);
191 cellWidget->blockSignals(true);
192 cellWidget->setValue(cellValue);
193 cellWidget->blockSignals(false);
194 }
195 }
196
197 break;
198 }
199 }
200 }
201
202 /*
203 * Finds the position for the given cell widget.
204 */
205 QPair<int, int> SubfileReferenceEditor::cellPosition(QDoubleSpinBox* cellWidget)
206 {
207 for (int row : {0, 1, 2})
208 for (int column : {0, 1, 2})
209 {
210 if (this->matrixCell(row, column) == cellWidget)
211 return {row, column};
212 }
213
214 throw std::out_of_range {"widget is not in the matrix"};
215 }
216
217 /*
218 * Updates the appropriate scaling vector element when a matrix cell is changed.
219 */
220 void SubfileReferenceEditor::matrixChanged()
221 {
222 QDoubleSpinBox* cellWidget = static_cast<QDoubleSpinBox*>(this->sender());
223
224 try
225 {
226 int column = this->cellPosition(cellWidget).second;
227 QDoubleSpinBox* spinbox = this->vectorElement(column);
228 spinbox->blockSignals(true);
229 spinbox->setValue(this->matrixScaling(column));
230 spinbox->blockSignals(false);
231 }
232 catch (const std::out_of_range&) {}
233 }

mercurial