src/document.cpp

changeset 197
0e729e681a2c
parent 191
d355d4c52d51
child 198
eb9d900dc79a
equal deleted inserted replaced
196:6bcb284679d4 197:0e729e681a2c
21 #include "document.h" 21 #include "document.h"
22 #include "ui_document.h" 22 #include "ui_document.h"
23 #include "model.h" 23 #include "model.h"
24 #include "modeleditor.h" 24 #include "modeleditor.h"
25 #include "ui/objecteditor.h" 25 #include "ui/objecteditor.h"
26 #include "linetypes/edge.h"
27 #include "linetypes/triangle.h"
28 #include "linetypes/quadrilateral.h"
26 29
27 Document::Document( 30 Document::Document(
28 Model* model, 31 Model* model,
29 DocumentManager* documents, 32 DocumentManager* documents,
30 const ldraw::ColorTable& colorTable, 33 const ldraw::ColorTable& colorTable,
48 this->ui.viewportFrame->setLayout(new QVBoxLayout{this->ui.listView}); 51 this->ui.viewportFrame->setLayout(new QVBoxLayout{this->ui.listView});
49 this->ui.viewportFrame->layout()->addWidget(this->canvas); 52 this->ui.viewportFrame->layout()->addWidget(this->canvas);
50 this->toolsBar->setOrientation(Qt::Vertical); 53 this->toolsBar->setOrientation(Qt::Vertical);
51 this->setMouseTracking(true); 54 this->setMouseTracking(true);
52 connect(this->ui.viewportListSplitter, &QSplitter::splitterMoved, this, &Document::splitterChanged); 55 connect(this->ui.viewportListSplitter, &QSplitter::splitterMoved, this, &Document::splitterChanged);
56 connect(this->canvas, &Canvas::mouseClick, this, &Document::canvasMouseClick);
57 connect(this->canvas, &Canvas::mouseMove, this, &Document::canvasMouseMove);
53 connect(this->canvas, &Canvas::newStatusText, this, &Document::newStatusText); 58 connect(this->canvas, &Canvas::newStatusText, this, &Document::newStatusText);
54 connect(this->canvas, &Canvas::selectionChanged, [&](const QSet<ldraw::id_t>& newSelection) 59 connect(this->canvas, &Canvas::selectionChanged, [&](const QSet<ldraw::id_t>& newSelection)
55 { 60 {
56 QItemSelectionModel* selectionModel = this->ui.listView->selectionModel(); 61 QItemSelectionModel* selectionModel = this->ui.listView->selectionModel();
57 QItemSelection selection; 62 QItemSelection selection;
151 } 156 }
152 this->ui.toolWidgetStack->addWidget(widget); 157 this->ui.toolWidgetStack->addWidget(widget);
153 this->toolActions.push_back(action); 158 this->toolActions.push_back(action);
154 connect(action, &QAction::triggered, this, &Document::editingModeTriggered); 159 connect(action, &QAction::triggered, this, &Document::editingModeTriggered);
155 } 160 }
161 this->ui.listView->selectAll();
156 } 162 }
157 163
158 void Document::editingModeTriggered() 164 void Document::editingModeTriggered()
159 { 165 {
160 QAction* triggeredAction = qobject_cast<QAction*>(this->sender()); 166 QAction* triggeredAction = qobject_cast<QAction*>(this->sender());
161 if (triggeredAction != nullptr) 167 if (triggeredAction != nullptr)
162 { 168 {
163 const int index = triggeredAction->property(INDEX_PROPERTY).toInt(); 169 const int index = triggeredAction->property(INDEX_PROPERTY).toInt();
164 this->canvas->mode = static_cast<EditingMode>(index); 170 this->mode = static_cast<EditingMode>(index);
165 this->ui.toolWidgetStack->setCurrentIndex(index); 171 this->ui.toolWidgetStack->setCurrentIndex(index);
166 for (QAction* action : this->toolActions) { 172 for (QAction* action : this->toolActions) {
167 action->setChecked(action == triggeredAction); 173 action->setChecked(action == triggeredAction);
168 } 174 }
169 } 175 }
170 } 176 }
171 177
178 void updatePreviewPolygon(DrawState* drawState)
179 {
180 drawState->previewPolygon = drawState->polygon;
181 drawState->previewPolygon.resize(drawState->polygon.size() + 1);
182 drawState->previewPolygon.back() = drawState->previewPoint;
183 if (drawState->previewPolygon.size() > 2)
184 {
185 drawState->isconcave = not geom::isConvex(drawState->previewPolygon);
186 }
187 }
188
189 void removeLastPoint(DrawState* drawState)
190 {
191 if (drawState->polygon.size() > 0)
192 {
193 drawState->polygon.erase(drawState->polygon.end() - 1);
194 updatePreviewPolygon(drawState);
195 }
196 }
197
198 bool isCloseToExistingPoints(const std::vector<glm::vec3>& points, const glm::vec3 &pos)
199 {
200 return any(points, std::bind(geom::isclose, std::placeholders::_1, pos));
201 }
202
203 void Document::canvasMouseClick(QMouseEvent *event)
204 {
205 switch(this->mode)
206 {
207 case SelectMode:
208 if (event->button() == Qt::LeftButton)
209 {
210 const ldraw::id_t highlighted = this->canvas->getHighlightedObject();
211 QSet<ldraw::id_t> selected;
212 if (highlighted != ldraw::NULL_ID) {
213 selected.insert(highlighted);
214 }
215 this->select(selected);
216 event->accept();
217 }
218 break;
219 case DrawMode:
220 if (event->button() == Qt::LeftButton and this->canvas->worldPosition.has_value())
221 {
222 const glm::vec3& pos = this->canvas->worldPosition.value();
223 if (isCloseToExistingPoints(this->drawState.polygon, pos))
224 {
225 this->closeShape();
226 }
227 else
228 {
229 this->drawState.polygon.push_back(pos);
230 updatePreviewPolygon(&this->drawState);
231 }
232 event->accept();
233 }
234 else if (true
235 and event->button() == Qt::RightButton
236 and this->drawState.polygon.size() > 0
237 ) {
238 this->drawState.polygon.erase(this->drawState.polygon.end() - 1);
239 updatePreviewPolygon(&this->drawState);
240 event->accept();
241 }
242 break;
243 }
244 }
245
246 void Document::canvasMouseMove(QMouseEvent *event)
247 {
248 switch(this->mode)
249 {
250 case SelectMode:
251 break;
252 case DrawMode:
253 if (this->canvas->worldPosition.has_value())
254 {
255 this->drawState.previewPoint = this->canvas->worldPosition.value();
256 updatePreviewPolygon(&this->drawState);
257 this->update();
258 }
259 event->accept();
260 break;
261 }
262 }
263
264 void Document::select(const QSet<ldraw::id_t> &selected)
265 {
266 QItemSelectionModel* selectionModel = this->ui.listView->selectionModel();
267 QItemSelection itemSelection;
268 for (const ldraw::id_t id : selected)
269 {
270 QModelIndex index = this->model->find(id);
271 if (index != QModelIndex{})
272 {
273 itemSelection.select(index, index);
274 }
275 }
276 selectionModel->select(itemSelection, QItemSelectionModel::ClearAndSelect);
277 }
278
172 const Model &Document::getModel() const 279 const Model &Document::getModel() const
173 { 280 {
174 return *this->model; 281 return *this->model;
175 } 282 }
176 283
177 const QSet<ldraw::id_t> Document::selectedObjects() const 284 const QSet<ldraw::id_t> Document::selectedObjects() const
178 { 285 {
179 return this->canvas->selectedObjects(); 286 return this->canvas->selectedObjects();
180 } 287 }
288
289 void Document::closeShape()
290 {
291 if (this->drawState.polygon.size() >= 2 and this->drawState.polygon.size() <= 4)
292 {
293 std::unique_ptr<ModelEditor> modelEditor = this->editModel();
294 switch (this->drawState.polygon.size())
295 {
296 case 2:
297 modelEditor->append<ldraw::Edge>(
298 vectorToArray<2>(this->drawState.polygon),
299 ldraw::EDGE_COLOR);
300 break;
301 case 3:
302 modelEditor->append<ldraw::Triangle>(
303 vectorToArray<3>(this->drawState.polygon),
304 ldraw::MAIN_COLOR);
305 break;
306 case 4:
307 modelEditor->append<ldraw::Quadrilateral>(
308 vectorToArray<4>(this->drawState.polygon),
309 ldraw::MAIN_COLOR);
310 break;
311 }
312 }
313 this->drawState.polygon.clear();
314 updatePreviewPolygon(&this->drawState);
315 }

mercurial