work on editing tools

Sun, 25 Jul 2021 13:49:37 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 25 Jul 2021 13:49:37 +0300
changeset 108
94c92c923713
parent 107
02f142b399b1
child 109
40a1cf2f38f5

work on editing tools

src/document.cpp file | annotate | diff | comparison | revisions
src/document.h file | annotate | diff | comparison | revisions
src/geometry.h file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h 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.cpp file | annotate | diff | comparison | revisions
src/ui/canvas.h file | annotate | diff | comparison | revisions
--- a/src/document.cpp	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/document.cpp	Sun Jul 25 13:49:37 2021 +0300
@@ -72,6 +72,7 @@
 	});
 	connect(this->model, &Model::dataChanged, this->renderer, qOverload<>(&Canvas::update));
 	connect(this->renderer, &Canvas::mouseClick, this, &Document::mouseClick);
+	connect(this->renderer, &Canvas::mouseMove, this, &Document::mouseMove);
 }
 
 Document::~Document()
--- a/src/document.h	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/document.h	Sun Jul 25 13:49:37 2021 +0300
@@ -46,6 +46,7 @@
 	void newStatusText(const QString& newStatusText);
 	void splitterChanged();
 	void mouseClick(const Canvas::MouseClickInfo& info);
+	void mouseMove(const Canvas::MouseMoveInfo& info);
 private:
 	void selectionChanged(const QSet<ldraw::id_t>& newSelection);
 	Model* model;
--- a/src/geometry.h	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/geometry.h	Sun Jul 25 13:49:37 2021 +0300
@@ -103,10 +103,31 @@
 		std::vector<glm::vec3> points;
 	};
 
-	inline bool isclose(const glm::vec3& a, const glm::vec3& b)
+	inline constexpr bool isclose(const glm::vec3& a, const glm::vec3& b)
 	{
 		return qFuzzyCompare(a.x, b.x)
 			and qFuzzyCompare(a.y, b.y)
 			and qFuzzyCompare(a.z, b.z);
 	}
+
+	struct CircleF
+	{
+		QPointF center;
+		qreal radius;
+	};
+
+	/**
+	 * @param center
+	 * @param radius
+	 * @returns a QRectF that encloses the specified circle
+	 */
+	inline constexpr QRectF inscribe(const CircleF& circle)
+	{
+		return {
+			circle.center.x() - circle.radius,
+			circle.center.y() - circle.radius,
+			circle.radius * 2,
+			circle.radius * 2
+		};
+	}
 }
--- a/src/mainwindow.cpp	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/mainwindow.cpp	Sun Jul 25 13:49:37 2021 +0300
@@ -213,6 +213,7 @@
 	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);
 }
 
 void MainWindow::runSettingsEditor()
@@ -429,9 +430,12 @@
 	Q_UNUSED(event)
 }
 
-void MainWindow::canvasMouseMoved(QMouseEvent* event)
+void MainWindow::canvasMouseMoved(const Canvas::MouseMoveInfo& info)
 {
-	Q_UNUSED(event)
+	if (this->selectedTool != nullptr)
+	{
+		this->selectedTool->mouseMove(info);
+	}
 }
 
 void MainWindow::canvasKeyReleased(QKeyEvent* event)
--- a/src/mainwindow.h	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/mainwindow.h	Sun Jul 25 13:49:37 2021 +0300
@@ -78,6 +78,6 @@
 	void canvasMousePressed(QMouseEvent* event);
 	void canvasMouseReleased(const Canvas::MouseClickInfo& info);
 	void canvasMouseDoubleClicked(QMouseEvent* event);
-	void canvasMouseMoved(QMouseEvent*);
+	void canvasMouseMoved(const Canvas::MouseMoveInfo& info);
 	void canvasKeyReleased(QKeyEvent*);
 };
--- a/src/tools/basetool.h	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/tools/basetool.h	Sun Jul 25 13:49:37 2021 +0300
@@ -15,7 +15,7 @@
 	virtual bool mousePressed(QMouseEvent*) { return false; }
 	virtual bool mouseClick(const Canvas::MouseClickInfo&) { return false; }
 	virtual bool mouseDoubleClicked(QMouseEvent*) { return false; }
-	virtual bool mouseMoved(QMouseEvent*) { return false; }
+	virtual bool mouseMove(const Canvas::MouseMoveInfo&) { return false; }
 	virtual bool keyReleased(QKeyEvent*) { return false; }
 	virtual void reset() {}
 };
--- a/src/tools/drawtool.cpp	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/tools/drawtool.cpp	Sun Jul 25 13:49:37 2021 +0300
@@ -1,6 +1,10 @@
 #include <QMessageBox>
 #include "drawtool.h"
 
+static const QBrush brush = {Qt::white};
+static const QPen pen = {Qt::black};
+static const QBrush polygonBrush = {QColor{64, 255, 128}};
+
 DrawTool::DrawTool(QObject* parent) :
 	BaseTool{parent} {}
 
@@ -29,9 +33,11 @@
 		else
 		{
 			this->polygon.push_back(pos);
-			auto& previewLayer = info.invoker->modifyPreviewLayer(Canvas::DrawToolPreview).polygons;
-			previewLayer.clear();
-			previewLayer.push_back({this->polygon});
+			auto& previewLayer = info.invoker->modifyPreviewLayer(Canvas::DrawToolPreview);
+			previewLayer.points.resize(this->polygon.size());
+			previewLayer.points.back() = {pos, brush, pen};
+			previewLayer.polygons.clear();
+			previewLayer.polygons.push_back({geom::NPolygon{this->polygon}, polygonBrush, pen});
 			if (this->polygon.size() == 4)
 			{
 				QMessageBox::information(nullptr, "test", "close the polygon");
@@ -41,6 +47,27 @@
 	return true;
 }
 
+bool DrawTool::mouseMove(const Canvas::MouseMoveInfo& info)
+{
+	if (this->polygon.size() < 4 and info.worldPosition.has_value())
+	{
+		auto& previewLayer = info.invoker->modifyPreviewLayer(Canvas::DrawToolPreview);
+		previewLayer.points.resize(this->polygon.size() + 1);
+		previewLayer.points.back() = {info.worldPosition.value(), brush, pen};
+		if (previewLayer.polygons.size() > 0)
+		{
+			auto& polygon = previewLayer.polygons.back();
+			polygon.geometry.points.resize(this->polygon.size() + 1);
+			polygon.geometry.points.back() = info.worldPosition.value();
+		}
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
 void DrawTool::reset()
 {
 	this->polygon.clear();
--- a/src/tools/drawtool.h	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/tools/drawtool.h	Sun Jul 25 13:49:37 2021 +0300
@@ -11,6 +11,7 @@
 	QString name() const override;
 	QString toolTip() const override;
 	bool mouseClick(const Canvas::MouseClickInfo& info) override;
+	bool mouseMove(const Canvas::MouseMoveInfo&) override;
 	void reset() override;
 private:
 	std::vector<glm::vec3> polygon;
--- a/src/ui/canvas.cpp	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/ui/canvas.cpp	Sun Jul 25 13:49:37 2021 +0300
@@ -77,6 +77,10 @@
 		this->updateGridMatrix();
 		this->update();
 	}
+	MouseMoveInfo info;
+	info.invoker = this;
+	info.worldPosition = this->worldPosition;
+	emit mouseMove(info);
 	PartRenderer::mouseMoveEvent(event);
 }
 
@@ -225,16 +229,27 @@
 			}
 			for (const PreviewLayer& previewLayer : this->previewLayers)
 			{
-				painter.setBrush({previewLayer.color});
-				for (const geom::NPolygon& polygon3d : previewLayer.polygons)
+				for (const PreviewLayer::Polygon& polygon3d : previewLayer.polygons)
 				{
+					painter.setBrush(polygon3d.brush);
+					painter.setPen(polygon3d.pen);
 					QVector<QPointF> points2d;
-					points2d.reserve(polygon3d.points.size());
-					for (const glm::vec3& point : polygon3d.points)
+					points2d.reserve(polygon3d.geometry.points.size());
+					for (const glm::vec3& point : polygon3d.geometry.points)
 					{
 						points2d.push_back(this->modelToScreenCoordinates(point));
 					}
-					painter.drawPolygon({points2d});
+					painter.drawPolygon(QPolygonF{points2d});
+				}
+				for (const PreviewLayer::Point& point : previewLayer.points)
+				{
+					const geom::CircleF circle = {
+						this->modelToScreenCoordinates(point.location),
+						5.0,
+					};
+					painter.setBrush(point.brush);
+					painter.setPen(point.pen);
+					painter.drawEllipse(geom::inscribe(circle));
 				}
 			}
 		}
--- a/src/ui/canvas.h	Sat Jul 24 01:50:38 2021 +0300
+++ b/src/ui/canvas.h	Sun Jul 25 13:49:37 2021 +0300
@@ -1,4 +1,6 @@
 #pragma once
+#include <QBrush>
+#include <QPen>
 #include "gl/partrenderer.h"
 #include "gl/gridprogram.h"
 #include "gl/axesprogram.h"
@@ -8,14 +10,27 @@
 	Q_OBJECT
 public:
 	struct MouseClickInfo;
+	struct MouseMoveInfo;
 	enum PreviewLayerName : std::int8_t
 	{
 		DrawToolPreview
 	};
 	struct PreviewLayer
 	{
-		QVector<geom::NPolygon> polygons;
-		QColor color{64, 255, 128};
+		struct Point
+		{
+			glm::vec3 location;
+			QBrush brush = {};
+			QPen pen = {};
+		};
+		struct Polygon
+		{
+			geom::NPolygon geometry;
+			QBrush brush = {};
+			QPen pen = {};
+		};
+		QVector<Point> points;
+		QVector<Polygon> polygons;
 	};
 	static constexpr int NUM_PREVIEW_LAYERS = 1;
 
@@ -40,6 +55,7 @@
 	void newStatusText(const QString& newStatusText);
 	void selectionChanged(const QSet<ldraw::id_t>& newSelection);
 	void mouseClick(const MouseClickInfo& info);
+	void mouseMove(const MouseMoveInfo& info);
 private:
 	void updateGridMatrix();
 	glm::vec3 cameraVector() const;
@@ -59,3 +75,9 @@
 	std::optional<glm::vec3> worldPosition;
 	Canvas* invoker;
 };
+
+struct Canvas::MouseMoveInfo
+{
+	std::optional<glm::vec3> worldPosition;
+	Canvas* invoker;
+};

mercurial