26 #include "settingseditor/settingseditor.h" |
26 #include "settingseditor/settingseditor.h" |
27 #include "version.h" |
27 #include "version.h" |
28 #include "document.h" |
28 #include "document.h" |
29 #include "uiutilities.h" |
29 #include "uiutilities.h" |
30 #include "widgets/colorselectdialog.h" |
30 #include "widgets/colorselectdialog.h" |
31 #include "tools/basetool.h" |
|
32 #include "tools/drawtool.h" |
|
33 #include "tools/selecttool.h" |
|
34 |
|
35 static const QMetaObject* const toolMetaObjects[] = { |
|
36 &SelectTool::staticMetaObject, |
|
37 &DrawTool::staticMetaObject, |
|
38 }; |
|
39 |
31 |
40 template<typename BaseType, typename MemberType, typename DataType> |
32 template<typename BaseType, typename MemberType, typename DataType> |
41 struct MemberData |
33 struct MemberData |
42 { |
34 { |
43 std::size_t member; |
35 std::size_t member; |
84 this->updateTitle(); |
76 this->updateTitle(); |
85 this->restoreStartupSettings(); |
77 this->restoreStartupSettings(); |
86 this->restoreSettings(); |
78 this->restoreSettings(); |
87 this->updateRenderPreferences(); |
79 this->updateRenderPreferences(); |
88 this->newModel(); |
80 this->newModel(); |
89 |
|
90 for (const QMetaObject* const metaObject : ::toolMetaObjects) |
|
91 { |
|
92 QObject* const objectInstance = metaObject->newInstance(Q_ARG(QObject*, this)); |
|
93 BaseTool* const toolInstance = qobject_cast<BaseTool*>(objectInstance); |
|
94 if (toolInstance) |
|
95 { |
|
96 this->tools.append(toolInstance); |
|
97 QAction* action = new QAction{toolInstance->name(), this}; |
|
98 action->setCheckable(true); |
|
99 this->toolActions[toolInstance] = action; |
|
100 action->setToolTip(toolInstance->toolTip()); |
|
101 connect(action, &QAction::triggered, this, &MainWindow::toolActionTriggered); |
|
102 this->ui->toolsBar->addAction(action); |
|
103 } |
|
104 else |
|
105 { |
|
106 QMessageBox::critical(this, tr("Error"), tr("Unable to construct %1").arg(metaObject->className())); |
|
107 } |
|
108 } |
|
109 |
|
110 this->selectTool(this->tools[0]); |
|
111 } |
81 } |
112 |
82 |
113 // MainWindow needs a destructor even if it is empty because otherwise the destructor of the |
83 // MainWindow needs a destructor even if it is empty because otherwise the destructor of the |
114 // std::unique_ptr is resolved in the header file, where it will complain about Ui_MainWindow |
84 // std::unique_ptr is resolved in the header file, where it will complain about Ui_MainWindow |
115 // being incomplete. |
85 // being incomplete. |
209 this->statusBar()->showMessage(newStatusText); |
179 this->statusBar()->showMessage(newStatusText); |
210 }); |
180 }); |
211 this->ui->tabs->addTab(document, modelName); |
181 this->ui->tabs->addTab(document, modelName); |
212 this->ui->tabs->setCurrentWidget(document); |
182 this->ui->tabs->setCurrentWidget(document); |
213 document->restoreSplitterState(this->documentSplitterState); |
183 document->restoreSplitterState(this->documentSplitterState); |
214 connect(document, &Document::splitterChanged, this, &MainWindow::handleDocumentSplitterChange); |
|
215 connect(document, &Document::mouseClick, this, &MainWindow::canvasMouseReleased); |
|
216 connect(document, &Document::mouseMove, this, &MainWindow::canvasMouseMoved); |
|
217 connect(document, &Document::keyReleased, this, &MainWindow::canvasKeyReleased); |
|
218 document->setCanvasOverpaintCallback([&](Canvas* canvas, QPainter* painter) |
|
219 { |
|
220 if (this->selectedTool != nullptr) |
|
221 { |
|
222 this->selectedTool->overpaint(canvas, painter); |
|
223 } |
|
224 }); |
|
225 } |
184 } |
226 |
185 |
227 void MainWindow::runSettingsEditor() |
186 void MainWindow::runSettingsEditor() |
228 { |
187 { |
229 SettingsEditor settingsEditor{&this->settings, this->defaultKeyboardShortcuts, this}; |
188 SettingsEditor settingsEditor{&this->settings, this->defaultKeyboardShortcuts, this}; |
232 { |
191 { |
233 this->restoreSettings(); |
192 this->restoreSettings(); |
234 } |
193 } |
235 } |
194 } |
236 |
195 |
|
196 Document* MainWindow::currentDocument() |
|
197 { |
|
198 return qobject_cast<Document*>(this->ui->tabs->currentWidget()); |
|
199 } |
|
200 |
237 void MainWindow::handleDocumentSplitterChange() |
201 void MainWindow::handleDocumentSplitterChange() |
238 { |
202 { |
239 Document* currentDocument = qobject_cast<Document*>(this->ui->tabs->currentWidget()); |
203 Document* currentDocument = this->currentDocument(); |
240 if (currentDocument != nullptr) |
204 if (currentDocument != nullptr) |
241 { |
205 { |
242 this->documentSplitterState = currentDocument->saveSplitterState(); |
206 this->documentSplitterState = currentDocument->saveSplitterState(); |
243 for (int i = 0; i < this->ui->tabs->count(); i += 1) |
207 for (int i = 0; i < this->ui->tabs->count(); i += 1) |
244 { |
208 { |
385 { |
349 { |
386 QTextStream errors; |
350 QTextStream errors; |
387 this->colorTable = this->libraries.loadColorTable(errors); |
351 this->colorTable = this->libraries.loadColorTable(errors); |
388 } |
352 } |
389 |
353 |
390 void MainWindow::toolActionTriggered() |
354 void MainWindow::keyReleaseEvent(QKeyEvent* event) |
391 { |
355 { |
392 QAction* action = qobject_cast<QAction*>(sender()); |
356 Document* document = this->currentDocument(); |
393 if (action != nullptr) |
357 if (document != nullptr) |
394 { |
358 { |
395 BaseTool* tool = nullptr; |
359 document->handleKeyPress(event); |
396 for (auto&& pair : items(this->toolActions)) |
360 } |
397 { |
361 } |
398 if (pair.value == action) |
|
399 { |
|
400 tool = pair.key; |
|
401 } |
|
402 } |
|
403 this->selectTool(tool); |
|
404 } |
|
405 } |
|
406 |
|
407 void MainWindow::selectTool(BaseTool* tool) |
|
408 { |
|
409 if (tool != nullptr && tool != this->selectedTool) |
|
410 { |
|
411 if (this->selectedTool != nullptr) |
|
412 { |
|
413 this->selectedTool->reset(); |
|
414 } |
|
415 this->selectedTool = tool; |
|
416 for (auto&& pair : items(this->toolActions)) |
|
417 { |
|
418 pair.value->setChecked(pair.key == tool); |
|
419 } |
|
420 } |
|
421 } |
|
422 |
|
423 void MainWindow::canvasMousePressed(QMouseEvent *event) |
|
424 { |
|
425 Q_UNUSED(event) |
|
426 } |
|
427 |
|
428 void MainWindow::canvasMouseReleased(Document* document, Canvas* canvas, QMouseEvent* event) |
|
429 { |
|
430 if (this->selectedTool != nullptr) |
|
431 { |
|
432 this->selectedTool->mouseClick(document, canvas, event); |
|
433 } |
|
434 } |
|
435 |
|
436 void MainWindow::canvasMouseDoubleClicked(QMouseEvent* event) |
|
437 { |
|
438 Q_UNUSED(event) |
|
439 } |
|
440 |
|
441 void MainWindow::canvasMouseMoved(Document* document, Canvas* canvas, QMouseEvent* event) |
|
442 { |
|
443 if (this->selectedTool != nullptr) |
|
444 { |
|
445 this->selectedTool->mouseMove(document, canvas, event); |
|
446 } |
|
447 } |
|
448 |
|
449 void MainWindow::keyReleaseEvent(QKeyEvent *event) |
|
450 { |
|
451 if (this->selectedTool != nullptr) |
|
452 { |
|
453 this->selectedTool->keyReleased(event); |
|
454 } |
|
455 } |
|
456 |
|
457 void MainWindow::canvasKeyReleased(Document *document, Canvas *canvas, QKeyEvent *event) |
|
458 { |
|
459 #if 0 |
|
460 if (this->selectedTool != nullptr) |
|
461 { |
|
462 this->selectedTool->keyReleased(document, canvas, event); |
|
463 } |
|
464 #endif |
|
465 } |
|