src/dialogs/subfilereferenceeditor.cpp

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

mercurial