src/document.cpp

changeset 125
f127982d3412
parent 124
f9f308c8e0c5
child 126
a7c720aff97c
--- a/src/document.cpp	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/document.cpp	Sun Aug 29 20:39:55 2021 +0300
@@ -17,10 +17,19 @@
  */
 
 #include <QMouseEvent>
+#include <QMessageBox>
 #include "document.h"
 #include "ui_document.h"
 #include "model.h"
 #include "modeleditcontext.h"
+#include "tools/basetool.h"
+#include "tools/drawtool.h"
+#include "tools/selecttool.h"
+
+static const QMetaObject* const toolMetaObjects[] = {
+	&SelectTool::staticMetaObject,
+	&DrawTool::staticMetaObject,
+};
 
 Document::Document(
 	Model* model,
@@ -34,14 +43,18 @@
 	vertexMap{model},
 	renderer{new Canvas{model, documents, colorTable, this}},
 	ui{*new Ui::Document},
-	objectEditor{model, ldraw::NULL_ID, this}
+	objectEditor{model, ldraw::NULL_ID, this},
+	toolsBar{new QToolBar{this}}
 {
 	this->ui.setupUi(this);
+	this->ui.toolsBarContainer->setLayout(new QVBoxLayout{this->ui.toolsBarContainer});
+	this->ui.toolsBarContainer->layout()->addWidget(this->toolsBar);
 	this->ui.listView->setModel(model);
 	this->ui.viewportFrame->setLayout(new QVBoxLayout{this->ui.listView});
 	this->ui.viewportFrame->layout()->addWidget(this->renderer);
 	this->ui.objectEditorFrame->setLayout(new QVBoxLayout{this->ui.objectEditorFrame});
 	this->ui.objectEditorFrame->layout()->addWidget(&this->objectEditor);
+	this->toolsBar->setOrientation(Qt::Vertical);
 	this->setMouseTracking(true);
 	connect(this->ui.splitter, &QSplitter::splitterMoved, this, &Document::splitterChanged);
 	connect(this->renderer, &Canvas::newStatusText, this, &Document::newStatusText);
@@ -75,20 +88,30 @@
 	connect(this->model, &Model::dataChanged, this->renderer, qOverload<>(&Canvas::update));
 	connect(this->renderer, &Canvas::mouseClick, this, [this](Canvas* canvas, QMouseEvent* event)
 	{
-		Q_EMIT this->mouseClick(this, canvas, event);
+		if (this->selectedTool != nullptr)
+		{
+			this->selectedTool->mouseClick(this, canvas, event);
+		}
 	});
 	connect(this->renderer, &Canvas::mouseMove, this, [this](Canvas* canvas, QMouseEvent* event)
 	{
-		Q_EMIT this->mouseMove(this, canvas, event);
-	});
-	connect(this->renderer, &Canvas::keyReleased, this, [this](Canvas* canvas, QKeyEvent* event)
-	{
-		Q_EMIT this->keyReleased(this, canvas, event);
+		if (this->selectedTool != nullptr)
+		{
+			this->selectedTool->mouseMove(this, canvas, event);
+		}
 	});
 	connect(&this->vertexMap, &VertexMap::verticesChanged, [&]()
 	{
 		this->renderer->rebuildVertices(this);
 	});
+	this->setCanvasOverpaintCallback([&](Canvas* canvas, QPainter* painter)
+	{
+		if (this->selectedTool != nullptr)
+		{
+			this->selectedTool->overpaint(canvas, painter);
+		}
+	});
+	this->initializeTools();
 }
 
 Document::~Document()
@@ -137,3 +160,68 @@
 		this->objectEditor.setObjectId(ldraw::NULL_ID);
 	}
 }
+
+void Document::initializeTools()
+{
+	for (const QMetaObject* const metaObject : ::toolMetaObjects)
+	{
+		QObject* const objectInstance = metaObject->newInstance(Q_ARG(QObject*, this));
+		BaseTool* const toolInstance = qobject_cast<BaseTool*>(objectInstance);
+		if (toolInstance)
+		{
+			this->tools.append(toolInstance);
+			QAction* action = new QAction{toolInstance->name(), this};
+			action->setCheckable(true);
+			this->toolActions[toolInstance] = action;
+			action->setToolTip(toolInstance->toolTip());
+			connect(action, &QAction::triggered, this, &Document::toolActionTriggered);
+			this->toolsBar->addAction(action);
+		}
+		else
+		{
+			QMessageBox::critical(this, tr("Error"), tr("Unable to construct %1").arg(metaObject->className()));
+		}
+	}
+	this->selectTool(this->tools[0]);
+}
+
+void Document::toolActionTriggered()
+{
+	QAction* action = qobject_cast<QAction*>(sender());
+	if (action != nullptr)
+	{
+		BaseTool* tool = nullptr;
+		for (auto&& pair : items(this->toolActions))
+		{
+			if (pair.value == action)
+			{
+				tool = pair.key;
+			}
+		}
+		this->selectTool(tool);
+	}
+}
+
+void Document::selectTool(BaseTool* tool)
+{
+	if (tool != nullptr && tool != this->selectedTool)
+	{
+		if (this->selectedTool != nullptr)
+		{
+			this->selectedTool->reset();
+		}
+		this->selectedTool = tool;
+		for (auto&& pair : items(this->toolActions))
+		{
+			pair.value->setChecked(pair.key == tool);
+		}
+	}
+}
+
+void Document::handleKeyPress(QKeyEvent* event)
+{
+	if (this->selectedTool != nullptr)
+	{
+		this->selectedTool->keyReleased(this, this->renderer, event);
+	}
+}

mercurial