src/ui/canvas.cpp

changeset 197
0e729e681a2c
parent 191
d355d4c52d51
child 198
eb9d900dc79a
--- a/src/ui/canvas.cpp	Wed May 25 17:56:30 2022 +0300
+++ b/src/ui/canvas.cpp	Wed May 25 18:29:49 2022 +0300
@@ -3,9 +3,6 @@
 #include "modeleditor.h"
 #include "document.h"
 #include "canvas.h"
-#include "linetypes/edge.h"
-#include "linetypes/triangle.h"
-#include "linetypes/quadrilateral.h"
 
 Canvas::Canvas(
 	Model* model,
@@ -46,31 +43,6 @@
 	}
 }
 
-void updatePreviewPolygon(DrawState* drawState)
-{
-	drawState->previewPolygon = drawState->polygon;
-	drawState->previewPolygon.resize(drawState->polygon.size() + 1);
-	drawState->previewPolygon.back() = drawState->previewPoint;
-	if (drawState->previewPolygon.size() > 2)
-	{
-		drawState->isconcave = not geom::isConvex(drawState->previewPolygon);
-	}
-}
-
-void removeLastPoint(DrawState* drawState)
-{
-	if (drawState->polygon.size() > 0)
-	{
-		drawState->polygon.erase(drawState->polygon.end() - 1);
-		updatePreviewPolygon(drawState);
-	}
-}
-
-bool isCloseToExistingPoints(const std::vector<glm::vec3>& points, const glm::vec3 &pos)
-{
-	return any(points, std::bind(geom::isclose, std::placeholders::_1, pos));
-}
-
 void Canvas::mouseMoveEvent(QMouseEvent* event)
 {
 	const ldraw::id_t id = this->pick(event->pos());
@@ -94,21 +66,7 @@
 		// grid matrix.
 		this->worldPosition = this->gridMatrix * glm::vec4{*this->worldPosition, 1};
 	}
-	switch(this->mode)
-	{
-	case SelectMode:
-		break;
-	case DrawMode:
-		const auto& worldPosition = this->getWorldPosition();
-		if (worldPosition.has_value())
-		{
-			this->drawState.previewPoint = worldPosition.value();
-			updatePreviewPolygon(&this->drawState);
-			this->update();
-		}
-		event->accept();
-		break;
-	}
+	Q_EMIT this->mouseMove(event);
 	PartRenderer::mouseMoveEvent(event);
 	this->update();
 }
@@ -124,45 +82,7 @@
 {
 	if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0)
 	{
-		switch(this->mode)
-		{
-		case SelectMode:
-			if (event->button() == Qt::LeftButton)
-			{
-				const ldraw::id_t highlighted = this->getHighlightedObject();
-				this->clearSelection();
-				if (highlighted != ldraw::NULL_ID)
-				{
-					this->addToSelection(highlighted);
-				}
-				event->accept();
-			}
-			break;
-		case DrawMode:
-			if (event->button() == Qt::LeftButton and this->worldPosition.has_value())
-			{
-				const glm::vec3& pos = worldPosition.value();
-				if (isCloseToExistingPoints(this->drawState.polygon, pos))
-				{
-					this->closeShape();
-				}
-				else
-				{
-					this->drawState.polygon.push_back(pos);
-					updatePreviewPolygon(&this->drawState);
-				}
-				event->accept();
-			}
-			else if (true
-				and event->button() == Qt::RightButton
-				and this->drawState.polygon.size() > 0
-			) {
-				this->drawState.polygon.erase(this->drawState.polygon.end() - 1);
-				updatePreviewPolygon(&this->drawState);
-				event->accept();
-			}
-			break;
-		}
+		Q_EMIT this->mouseClick(event);
 	}
 	PartRenderer::mouseReleaseEvent(event);
 	this->update();
@@ -208,6 +128,11 @@
 	const QBrush redPolygonBrush = {QColor{255, 96, 96, 192}};
 } pens;
 
+static void renderDrawState(
+	QPainter* painter,
+	Canvas* canvas,
+	DrawState* drawState);
+
 void Canvas::paintGL()
 {
 	PartRenderer::paintGL();
@@ -254,39 +179,49 @@
 		{
 			this->renderAxesLabels(painter);
 		}
-		switch(this->mode)
+		if (this->drawState != nullptr) {
+			renderDrawState(&painter, this, this->drawState);
+		}
+	}
+}
+
+static void renderDrawState(
+	QPainter* painter,
+	Canvas* canvas,
+	DrawState* drawState)
+{
+	switch(drawState->mode)
+	{
+	case SelectMode:
+		break;
+	case DrawMode:
 		{
-		case SelectMode:
-			break;
-		case DrawMode:
+			painter->setPen(drawState->isconcave ? ::pens.badPolygonPen : ::pens.polygonPen);
+			if (drawState->previewPolygon.size() > 2 and not drawState->isconcave)
 			{
-				painter.setPen(this->drawState.isconcave ? ::pens.badPolygonPen : ::pens.polygonPen);
-				if (this->drawState.previewPolygon.size() > 2 and not this->drawState.isconcave)
+				if (canvas->worldPolygonWinding(drawState->previewPolygon) == Winding::Clockwise)
 				{
-					if (this->worldPolygonWinding(this->drawState.previewPolygon) == Winding::Clockwise)
-					{
-						painter.setBrush(::pens.greenPolygonBrush);
-					}
-					else
-					{
-						painter.setBrush(::pens.redPolygonBrush);
-					}
-					this->drawWorldPolygon(&painter, this->drawState.previewPolygon);
+					painter->setBrush(::pens.greenPolygonBrush);
 				}
 				else
 				{
-					this->drawWorldPolyline(&painter, this->drawState.previewPolygon);
+					painter->setBrush(::pens.redPolygonBrush);
 				}
-				painter.setBrush(::pens.pointBrush);
-				painter.setPen(::pens.pointPen);
-				for (const glm::vec3& point : this->drawState.polygon)
-				{
-					this->drawWorldPoint(&painter, point);
-				}
-				this->drawWorldPoint(&painter, this->drawState.previewPoint);
+				canvas->drawWorldPolygon(painter, drawState->previewPolygon);
+			}
+			else
+			{
+				canvas->drawWorldPolyline(painter, drawState->previewPolygon);
 			}
-			break;
+			painter->setBrush(::pens.pointBrush);
+			painter->setPen(::pens.pointPen);
+			for (const glm::vec3& point : drawState->polygon)
+			{
+				canvas->drawWorldPoint(painter, point);
+			}
+			canvas->drawWorldPoint(painter, drawState->previewPoint);
 		}
+		break;
 	}
 }
 
@@ -414,34 +349,6 @@
 	return this->gridMatrix;
 }
 
-void Canvas::closeShape()
-{
-	if (this->drawState.polygon.size() >= 2 and this->drawState.polygon.size() <= 4)
-	{
-		std::unique_ptr<ModelEditor> modelEditor = this->document->editModel();
-		switch (this->drawState.polygon.size())
-		{
-		case 2:
-			modelEditor->append<ldraw::Edge>(
-				vectorToArray<2>(this->drawState.polygon),
-				ldraw::EDGE_COLOR);
-			break;
-		case 3:
-			modelEditor->append<ldraw::Triangle>(
-				vectorToArray<3>(this->drawState.polygon),
-				ldraw::MAIN_COLOR);
-			break;
-		case 4:
-			modelEditor->append<ldraw::Quadrilateral>(
-				vectorToArray<4>(this->drawState.polygon),
-				ldraw::MAIN_COLOR);
-			break;
-		}
-	}
-	this->drawState.polygon.clear();
-	updatePreviewPolygon(&this->drawState);
-}
-
 /**
  * @brief Paints a circle at where @c worldPoint is located on the screen.
  * @param painter Painter to use to render

mercurial