Move tools under Document instead of MainWindow

Sun, 29 Aug 2021 20:39:55 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 29 Aug 2021 20:39:55 +0300
changeset 125
f127982d3412
parent 124
f9f308c8e0c5
child 126
a7c720aff97c

Move tools under Document instead of MainWindow

src/document.cpp file | annotate | diff | comparison | revisions
src/document.h file | annotate | diff | comparison | revisions
src/document.ui file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/mainwindow.ui file | annotate | diff | comparison | revisions
src/tools/basetool.h file | annotate | diff | comparison | revisions
src/tools/drawtool.cpp file | annotate | diff | comparison | revisions
src/tools/drawtool.h file | annotate | diff | comparison | revisions
src/ui/canvas.h file | annotate | diff | comparison | revisions
--- 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);
+	}
+}
--- a/src/document.h	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/document.h	Sun Aug 29 20:39:55 2021 +0300
@@ -19,6 +19,7 @@
 #pragma once
 #include <memory>
 #include <QWidget>
+#include <QToolBar>
 #include "ui/canvas.h"
 #include "ui/objecteditor.h"
 #include "model.h"
@@ -45,6 +46,7 @@
 	void setCanvasOverpaintCallback(Canvas::OverpaintCallback fn);
 	Model::EditContext editModel();
 	void applyToVertices(VertexMap::ApplyFunction fn) const;
+	void handleKeyPress(QKeyEvent* event);
 Q_SIGNALS:
 	void newStatusText(const QString& newStatusText);
 	void splitterChanged();
@@ -52,6 +54,9 @@
 	void mouseMove(Document* document, Canvas* canvas, QMouseEvent* event);
 private:
 	void selectionChanged(const QSet<ldraw::id_t>& newSelection);
+	void initializeTools();
+	Q_SLOT void toolActionTriggered();
+	void selectTool(class BaseTool* tool);
 	Model* model;
 	DocumentManager* const documents;
 	const ldraw::ColorTable& colorTable;
@@ -59,4 +64,8 @@
 	Canvas* renderer;
 	Ui::Document& ui;
 	ObjectEditor objectEditor;
+	QToolBar* toolsBar;
+	QVector<class BaseTool*> tools;
+	BaseTool* selectedTool = nullptr;
+	QMap<BaseTool*, QAction*> toolActions;
 };
--- a/src/document.ui	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/document.ui	Sun Aug 29 20:39:55 2021 +0300
@@ -6,14 +6,17 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>795</width>
-    <height>414</height>
+    <width>957</width>
+    <height>540</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
+   <item>
+    <widget class="QWidget" name="toolsBarContainer" native="true"/>
+   </item>
    <item>
     <widget class="QSplitter" name="splitter_2">
      <property name="orientation">
--- a/src/mainwindow.cpp	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/mainwindow.cpp	Sun Aug 29 20:39:55 2021 +0300
@@ -28,14 +28,6 @@
 #include "document.h"
 #include "uiutilities.h"
 #include "widgets/colorselectdialog.h"
-#include "tools/basetool.h"
-#include "tools/drawtool.h"
-#include "tools/selecttool.h"
-
-static const QMetaObject* const toolMetaObjects[] = {
-	&SelectTool::staticMetaObject,
-	&DrawTool::staticMetaObject,
-};
 
 template<typename BaseType, typename MemberType, typename DataType>
 struct MemberData
@@ -86,28 +78,6 @@
 	this->restoreSettings();
 	this->updateRenderPreferences();
 	this->newModel();
-
-	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, &MainWindow::toolActionTriggered);
-			this->ui->toolsBar->addAction(action);
-		}
-		else
-		{
-			QMessageBox::critical(this, tr("Error"), tr("Unable to construct %1").arg(metaObject->className()));
-		}
-	}
-
-	this->selectTool(this->tools[0]);
 }
 
 // MainWindow needs a destructor even if it is empty because otherwise the destructor of the
@@ -211,17 +181,6 @@
 	this->ui->tabs->addTab(document, modelName);
 	this->ui->tabs->setCurrentWidget(document);
 	document->restoreSplitterState(this->documentSplitterState);
-	connect(document, &Document::splitterChanged, this, &MainWindow::handleDocumentSplitterChange);
-	connect(document, &Document::mouseClick, this, &MainWindow::canvasMouseReleased);
-	connect(document, &Document::mouseMove, this, &MainWindow::canvasMouseMoved);
-	connect(document, &Document::keyReleased, this, &MainWindow::canvasKeyReleased);
-	document->setCanvasOverpaintCallback([&](Canvas* canvas, QPainter* painter)
-	{
-		if (this->selectedTool != nullptr)
-		{
-			this->selectedTool->overpaint(canvas, painter);
-		}
-	});
 }
 
 void MainWindow::runSettingsEditor()
@@ -234,9 +193,14 @@
 	}
 }
 
+Document* MainWindow::currentDocument()
+{
+	return qobject_cast<Document*>(this->ui->tabs->currentWidget());
+}
+
 void MainWindow::handleDocumentSplitterChange()
 {
-	Document* currentDocument = qobject_cast<Document*>(this->ui->tabs->currentWidget());
+	Document* currentDocument = this->currentDocument();
 	if (currentDocument != nullptr)
 	{
 		this->documentSplitterState = currentDocument->saveSplitterState();
@@ -387,79 +351,11 @@
 	this->colorTable = this->libraries.loadColorTable(errors);
 }
 
-void MainWindow::toolActionTriggered()
+void MainWindow::keyReleaseEvent(QKeyEvent* event)
 {
-	QAction* action = qobject_cast<QAction*>(sender());
-	if (action != nullptr)
+	Document* document = this->currentDocument();
+	if (document != nullptr)
 	{
-		BaseTool* tool = nullptr;
-		for (auto&& pair : items(this->toolActions))
-		{
-			if (pair.value == action)
-			{
-				tool = pair.key;
-			}
-		}
-		this->selectTool(tool);
-	}
-}
-
-void MainWindow::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);
-		}
+		document->handleKeyPress(event);
 	}
 }
-
-void MainWindow::canvasMousePressed(QMouseEvent *event)
-{
-	Q_UNUSED(event)
-}
-
-void MainWindow::canvasMouseReleased(Document* document, Canvas* canvas, QMouseEvent* event)
-{
-	if (this->selectedTool != nullptr)
-	{
-		this->selectedTool->mouseClick(document, canvas, event);
-	}
-}
-
-void MainWindow::canvasMouseDoubleClicked(QMouseEvent* event)
-{
-	Q_UNUSED(event)
-}
-
-void MainWindow::canvasMouseMoved(Document* document, Canvas* canvas, QMouseEvent* event)
-{
-	if (this->selectedTool != nullptr)
-	{
-		this->selectedTool->mouseMove(document, canvas, event);
-	}
-}
-
-void MainWindow::keyReleaseEvent(QKeyEvent *event)
-{
-	if (this->selectedTool != nullptr)
-	{
-		this->selectedTool->keyReleased(event);
-	}
-}
-
-void MainWindow::canvasKeyReleased(Document *document, Canvas *canvas, QKeyEvent *event)
-{
-#if 0
-	if (this->selectedTool != nullptr)
-	{
-		this->selectedTool->keyReleased(document, canvas, event);
-	}
-#endif
-}
--- a/src/mainwindow.h	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/mainwindow.h	Sun Aug 29 20:39:55 2021 +0300
@@ -62,9 +62,6 @@
 	QStringList recentlyOpenedFiles;
 	ldraw::ColorTable colorTable;
 	gl::RenderPreferences renderPreferences;
-	QVector<class BaseTool*> tools;
-	BaseTool* selectedTool = nullptr;
-	QMap<BaseTool*, QAction*> toolActions;
 	void updateTitle();
 	void updateRenderPreferences();
 	void saveSettings();
@@ -75,11 +72,5 @@
 	void openModelForEditing(const QString& modelName);
 	static QString pathToTranslation(const QString& localeCode);
 	void loadColors();
-	Q_SLOT void toolActionTriggered();
-	void selectTool(BaseTool* tool);
-private Q_SLOTS:
-	void canvasMousePressed(QMouseEvent* event);
-	void canvasMouseReleased(Document *document, Canvas *canvas, QMouseEvent *event);
-	void canvasMouseDoubleClicked(QMouseEvent* event);
-	void canvasMouseMoved(Document *document, Canvas *canvas, QMouseEvent *event);
+	Document *currentDocument();
 };
--- a/src/mainwindow.ui	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/mainwindow.ui	Sun Aug 29 20:39:55 2021 +0300
@@ -26,7 +26,7 @@
      <x>0</x>
      <y>0</y>
      <width>800</width>
-     <height>26</height>
+     <height>34</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">
@@ -59,17 +59,6 @@
    <addaction name="menuView"/>
   </widget>
   <widget class="QStatusBar" name="statusbar"/>
-  <widget class="QToolBar" name="toolsBar">
-   <property name="windowTitle">
-    <string>toolBar</string>
-   </property>
-   <attribute name="toolBarArea">
-    <enum>LeftToolBarArea</enum>
-   </attribute>
-   <attribute name="toolBarBreak">
-    <bool>false</bool>
-   </attribute>
-  </widget>
   <action name="actionQuit">
    <property name="text">
     <string>Quit</string>
--- a/src/tools/basetool.h	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/tools/basetool.h	Sun Aug 29 20:39:55 2021 +0300
@@ -17,7 +17,7 @@
 	virtual bool mouseClick(Document*, Canvas*, QMouseEvent*) { return false; }
 	virtual bool mouseDoubleClicked(QMouseEvent*, QMouseEvent*) { return false; }
 	virtual bool mouseMove(Document*, Canvas*, QMouseEvent*) { return false; }
-	virtual bool keyReleased(QKeyEvent*) { return false; }
+	virtual bool keyReleased(Document*, Canvas*, QKeyEvent*) { return false; }
 	virtual void reset() {}
 	virtual void overpaint(Canvas*, QPainter*) const {}
 };
--- a/src/tools/drawtool.cpp	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/tools/drawtool.cpp	Sun Aug 29 20:39:55 2021 +0300
@@ -80,12 +80,13 @@
 	return false;
 }
 
-bool DrawTool::keyReleased(QKeyEvent* event)
+bool DrawTool::keyReleased(Document*, Canvas* canvas, QKeyEvent* event)
 {
 	if (event->key() == Qt::Key_Escape)
 	{
 		this->polygon.clear();
 		this->updatePreviewPolygon();
+		canvas->update();
 		return true;
 	}
 	else
--- a/src/tools/drawtool.h	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/tools/drawtool.h	Sun Aug 29 20:39:55 2021 +0300
@@ -12,7 +12,7 @@
 	QString toolTip() const override;
 	bool mouseClick(Document* document, Canvas* canvas, QMouseEvent* event) override;
 	bool mouseMove(Document* document, Canvas* canvas, QMouseEvent* event) override;
-	bool keyReleased(QKeyEvent*) override;
+	bool keyReleased(Document*, Canvas* canvas, QKeyEvent* event) override;
 	void reset() override;
 	void overpaint(Canvas*, QPainter*) const override;
 private:
--- a/src/ui/canvas.h	Sun Aug 29 20:05:24 2021 +0300
+++ b/src/ui/canvas.h	Sun Aug 29 20:39:55 2021 +0300
@@ -30,7 +30,6 @@
 	void mouseMoveEvent(QMouseEvent* event) override;
 	void mousePressEvent(QMouseEvent* event) override;
 	void mouseReleaseEvent(QMouseEvent* event) override;
-	void keyReleaseEvent(QKeyEvent *event) override;
 	void initializeGL() override;
 	void paintGL() override;
 Q_SIGNALS:

mercurial