| 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 } |