Draw tool actually adds objects now

Sun, 25 Jul 2021 20:29:14 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 25 Jul 2021 20:29:14 +0300
changeset 111
1f42c03fafca
parent 110
d922431eacf7
child 112
5760cbb32bc0

Draw tool actually adds objects now

src/document.cpp file | annotate | diff | comparison | revisions
src/document.h file | annotate | diff | comparison | revisions
src/gl/partrenderer.cpp file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/mainwindow.h file | annotate | diff | comparison | revisions
src/model.cpp file | annotate | diff | comparison | revisions
src/model.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/tools/selecttool.cpp file | annotate | diff | comparison | revisions
src/tools/selecttool.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	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/document.cpp	Sun Jul 25 20:29:14 2021 +0300
@@ -20,6 +20,7 @@
 #include "document.h"
 #include "ui_document.h"
 #include "model.h"
+#include "modeleditcontext.h"
 
 Document::Document(
 	Model* model,
@@ -71,8 +72,14 @@
 		this->selectionChanged(resolve(this->ui.listView->selectionModel()->selection()));
 	});
 	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);
+	connect(this->renderer, &Canvas::mouseClick, this, [this](Canvas* canvas)
+	{
+		Q_EMIT this->mouseClick(this, canvas);
+	});
+	connect(this->renderer, &Canvas::mouseMove, this, [this](Canvas* canvas)
+	{
+		Q_EMIT this->mouseMove(this, canvas);
+	});
 }
 
 Document::~Document()
@@ -100,6 +107,11 @@
 	this->renderer->setOverpaintCallback(fn);
 }
 
+Model::EditContext Document::editModel()
+{
+	return this->model->edit();
+}
+
 void Document::selectionChanged(const QSet<ldraw::id_t>& newSelection)
 {
 	if (newSelection.size() == 1)
--- a/src/document.h	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/document.h	Sun Jul 25 20:29:14 2021 +0300
@@ -21,14 +21,13 @@
 #include <QWidget>
 #include "ui/canvas.h"
 #include "ui/objecteditor.h"
+#include "model.h"
 
 namespace Ui
 {
 	class Document;
 }
 
-class Model;
-
 class Document : public QWidget
 {
 	Q_OBJECT
@@ -43,11 +42,12 @@
 	void restoreSplitterState(const QByteArray& state);
 	void setRenderPreferences(const gl::RenderPreferences& newPreferences);
 	void setCanvasOverpaintCallback(Canvas::OverpaintCallback fn);
+	Model::EditContext editModel();
 signals:
 	void newStatusText(const QString& newStatusText);
 	void splitterChanged();
-	void mouseClick(const Canvas::MouseClickInfo& info);
-	void mouseMove(const Canvas::MouseMoveInfo& info);
+	void mouseClick(Document* document, Canvas* canvas);
+	void mouseMove(Document* document, Canvas* canvas);
 private:
 	void selectionChanged(const QSet<ldraw::id_t>& newSelection);
 	Model* model;
--- a/src/gl/partrenderer.cpp	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/gl/partrenderer.cpp	Sun Jul 25 20:29:14 2021 +0300
@@ -38,6 +38,10 @@
 	compiler{new gl::Compiler{this->colorTable, this}}
 {
 	this->setMouseTracking(true);
+	connect(model, &Model::rowsInserted, [&]{
+		this->needBuild = true;
+	});
+	connect(model, &Model::rowsRemoved, [&]{ this->needBuild = true; });
 }
 
 PartRenderer::~PartRenderer()
--- a/src/mainwindow.cpp	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/mainwindow.cpp	Sun Jul 25 20:29:14 2021 +0300
@@ -424,11 +424,11 @@
 	Q_UNUSED(event)
 }
 
-void MainWindow::canvasMouseReleased(const Canvas::MouseClickInfo& info)
+void MainWindow::canvasMouseReleased(Document* document, Canvas* canvas)
 {
 	if (this->selectedTool != nullptr)
 	{
-		this->selectedTool->mouseClick(info);
+		this->selectedTool->mouseClick(document, canvas);
 	}
 }
 
@@ -437,11 +437,11 @@
 	Q_UNUSED(event)
 }
 
-void MainWindow::canvasMouseMoved(const Canvas::MouseMoveInfo& info)
+void MainWindow::canvasMouseMoved(Document* document, Canvas* canvas)
 {
 	if (this->selectedTool != nullptr)
 	{
-		this->selectedTool->mouseMove(info);
+		this->selectedTool->mouseMove(document, canvas);
 	}
 }
 
--- a/src/mainwindow.h	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/mainwindow.h	Sun Jul 25 20:29:14 2021 +0300
@@ -27,6 +27,8 @@
 #include "uiutilities.h"
 #include "ui/canvas.h"
 
+class Document;
+
 class MainWindow : public QMainWindow
 {
 	Q_OBJECT
@@ -76,8 +78,8 @@
 	void selectTool(BaseTool* tool);
 private slots:
 	void canvasMousePressed(QMouseEvent* event);
-	void canvasMouseReleased(const Canvas::MouseClickInfo& info);
+	void canvasMouseReleased(Document *document, Canvas *canvas);
 	void canvasMouseDoubleClicked(QMouseEvent* event);
-	void canvasMouseMoved(const Canvas::MouseMoveInfo& info);
+	void canvasMouseMoved(Document *document, Canvas *canvas);
 	void canvasKeyReleased(QKeyEvent*);
 };
--- a/src/model.cpp	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/model.cpp	Sun Jul 25 20:29:14 2021 +0300
@@ -124,6 +124,7 @@
 	emit beginInsertRows({}, position, position);
 	this->body.push_back(std::move(object));
 	emit endInsertRows();
+	this->needRecache = true;
 }
 
 void Model::remove(int position)
@@ -133,6 +134,7 @@
 		emit beginRemoveRows({}, position, position);
 		this->body.erase(std::begin(this->body) + position);
 		emit endRemoveRows();
+		this->needRecache = true;
 	}
 }
 
--- a/src/model.h	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/model.h	Sun Jul 25 20:29:14 2021 +0300
@@ -106,24 +106,27 @@
 template<typename T, typename... Args>
 ldraw::Id<T> Model::append(Args&&... args)
 {
-	emit layoutAboutToBeChanged();
+	const int position = static_cast<int>(this->body.size());
+	emit beginInsertRows({}, position, position);
 	this->body.push_back(std::make_unique<T>(args...));
 	ldraw::Object* pointer = this->body.back().get();
 	this->objectsById[pointer->id] = pointer;
 	emit objectAdded(pointer->id, static_cast<int>(this->body.size() - 1));
-	emit layoutChanged();
+	emit endInsertRows();
+	this->needRecache = true;
 	return ldraw::Id<T>{pointer->id.value};
 }
 
 template<typename T, typename... Args>
-ldraw::Id<T> Model::insert(std::size_t position, Args&&... args)
+ldraw::Id<T> Model::insert(const std::size_t position, Args&&... args)
 {
-	emit layoutAboutToBeChanged();
+	emit beginInsertRows({}, position, position);
 	this->body.insert(std::begin(this->body) + position, std::make_unique<T>(args...));
 	ldraw::Object* pointer = this->body[position].get();
 	this->objectsById[pointer->id] = pointer;
 	emit objectAdded(pointer->id, static_cast<int>(position));
-	emit layoutChanged();
+	emit endInsertRows();
+	this->needRecache = true;
 	return ldraw::Id<T>{pointer->id.value};
 }
 
--- a/src/tools/basetool.h	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/tools/basetool.h	Sun Jul 25 20:29:14 2021 +0300
@@ -3,6 +3,8 @@
 #include "../main.h"
 #include "../ui/canvas.h"
 
+class Document;
+
 class BaseTool : public QObject
 {
 	Q_OBJECT
@@ -13,9 +15,9 @@
 	virtual QString name() const = 0;
 	virtual QString toolTip() const = 0;
 	virtual bool mousePressed(QMouseEvent*) { return false; }
-	virtual bool mouseClick(const Canvas::MouseClickInfo&) { return false; }
+	virtual bool mouseClick(Document*, Canvas*) { return false; }
 	virtual bool mouseDoubleClicked(QMouseEvent*) { return false; }
-	virtual bool mouseMove(const Canvas::MouseMoveInfo&) { return false; }
+	virtual bool mouseMove(Document*, Canvas*) { return false; }
 	virtual bool keyReleased(QKeyEvent*) { return false; }
 	virtual void reset() {}
 	virtual void overpaint(Canvas*, QPainter*) const {}
--- a/src/tools/drawtool.cpp	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/tools/drawtool.cpp	Sun Jul 25 20:29:14 2021 +0300
@@ -1,5 +1,10 @@
 #include <QMessageBox>
+#include <document.h>
+#include "linetypes/edge.h"
+#include "linetypes/triangle.h"
+#include "linetypes/quadrilateral.h"
 #include "drawtool.h"
+#include "modeleditcontext.h"
 
 static const QBrush pointBrush = {Qt::white};
 static const QPen polygonPen = {QBrush{Qt::black}, 2.0, Qt::DashLine};
@@ -21,22 +26,23 @@
 	return result;
 }
 
-bool DrawTool::mouseClick(const Canvas::MouseClickInfo& info)
+bool DrawTool::mouseClick(Document* document, Canvas* canvas)
 {
-	if (info.worldPosition.has_value())
+	const auto& worldPosition = canvas->getWorldPosition();
+	if (worldPosition.has_value())
 	{
-		const glm::vec3& pos = info.worldPosition.value();
+		const glm::vec3& pos = worldPosition.value();
 		const auto isCloseToPos = [&](const glm::vec3& x){return geom::isclose(x, pos);};
 		if (any(this->polygon, isCloseToPos))
 		{
-			this->closeShape();
+			this->closeShape(document);
 		}
 		else
 		{
 			this->polygon.push_back(pos);
 			if (this->polygon.size() == 4)
 			{
-				this->closeShape();
+				this->closeShape(document);
 			}
 		}
 	}
@@ -44,11 +50,13 @@
 	return true;
 }
 
-bool DrawTool::mouseMove(const Canvas::MouseMoveInfo& info)
+bool DrawTool::mouseMove(Document* document, Canvas* canvas)
 {
-	if (info.worldPosition.has_value())
+	static_cast<void>(document);
+	const auto& worldPosition = canvas->getWorldPosition();
+	if (worldPosition.has_value())
 	{
-		this->previewPoint = info.worldPosition.value();
+		this->previewPoint = worldPosition.value();
 		if (this->polygon.size() < 4)
 		{
 			this->previewPolygon.resize(this->polygon.size() + 1);
@@ -80,7 +88,34 @@
 	}
 }
 
-void DrawTool::closeShape()
+template<std::size_t N, typename T>
+std::array<T, N> vectorToArray(const std::vector<T>& x)
+{
+	std::array<T, N> result;
+	for (std::size_t i = 0; i < x.size() and i < N; i += 1)
+	{
+		result[i] = x[i];
+	}
+	return result;
+}
+
+void DrawTool::closeShape(Document* document)
 {
-	QMessageBox::information(nullptr, "test", "close the polygon");
+	if (this->polygon.size() >= 2 and this->polygon.size() <= 4)
+	{
+		Model::EditContext edit = document->editModel();
+		switch (this->polygon.size())
+		{
+		case 2:
+			edit.append<ldraw::Edge>(vectorToArray<2>(this->polygon), ldraw::edgeColor);
+			break;
+		case 3:
+			edit.append<ldraw::Triangle>(vectorToArray<3>(this->polygon), ldraw::mainColor);
+			break;
+		case 4:
+			edit.append<ldraw::Quadrilateral>(vectorToArray<4>(this->polygon), ldraw::mainColor);
+			break;
+		}
+	}
+	this->polygon.clear();
 }
--- a/src/tools/drawtool.h	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/tools/drawtool.h	Sun Jul 25 20:29:14 2021 +0300
@@ -10,12 +10,12 @@
 
 	QString name() const override;
 	QString toolTip() const override;
-	bool mouseClick(const Canvas::MouseClickInfo& info) override;
-	bool mouseMove(const Canvas::MouseMoveInfo&) override;
+	bool mouseClick(Document* document, Canvas* canvas) override;
+	bool mouseMove(Document* document, Canvas* canvas) override;
 	void reset() override;
 	void overpaint(Canvas*, QPainter*) const override;
 private:
-	void closeShape();
+	void closeShape(Document *document);
 	std::vector<glm::vec3> polygon;
 	std::vector<glm::vec3> previewPolygon;
 	glm::vec3 previewPoint;
--- a/src/tools/selecttool.cpp	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/tools/selecttool.cpp	Sun Jul 25 20:29:14 2021 +0300
@@ -15,13 +15,14 @@
 	return result;
 }
 
-bool SelectTool::mouseClick(const Canvas::MouseClickInfo& info)
+bool SelectTool::mouseClick(Document* document, Canvas* canvas)
 {
-	const ldraw::id_t highlighted = info.invoker->getHighlightedObject();
-	info.invoker->clearSelection();
+	static_cast<void>(document);
+	const ldraw::id_t highlighted = canvas->getHighlightedObject();
+	canvas->clearSelection();
 	if (highlighted != ldraw::NULL_ID)
 	{
-		info.invoker->addToSelection(highlighted);
+		canvas->addToSelection(highlighted);
 	}
 	return true;
 }
--- a/src/tools/selecttool.h	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/tools/selecttool.h	Sun Jul 25 20:29:14 2021 +0300
@@ -10,5 +10,5 @@
 
 	QString name() const override;
 	QString toolTip() const override;
-	bool mouseClick(const Canvas::MouseClickInfo &info) override;
+	bool mouseClick(Document*, Canvas*) override;
 };
--- a/src/ui/canvas.cpp	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/ui/canvas.cpp	Sun Jul 25 20:29:14 2021 +0300
@@ -77,10 +77,7 @@
 		this->updateGridMatrix();
 		this->update();
 	}
-	MouseMoveInfo info;
-	info.invoker = this;
-	info.worldPosition = this->worldPosition;
-	emit mouseMove(info);
+	Q_EMIT this->mouseMove(this);
 	PartRenderer::mouseMoveEvent(event);
 }
 
@@ -95,10 +92,7 @@
 {
 	if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0)
 	{
-		MouseClickInfo info;
-		info.worldPosition = this->worldPosition;
-		info.invoker = this;
-		emit mouseClick(info);
+		Q_EMIT this->mouseClick(this);
 	}
 	PartRenderer::mouseReleaseEvent(event);
 }
--- a/src/ui/canvas.h	Sun Jul 25 16:29:08 2021 +0300
+++ b/src/ui/canvas.h	Sun Jul 25 20:29:14 2021 +0300
@@ -10,8 +10,6 @@
 {
 	Q_OBJECT
 public:
-	struct MouseClickInfo;
-	struct MouseMoveInfo;
 	using OverpaintCallback = std::function<void(Canvas*, QPainter*)>;
 	Canvas(
 		Model* model,
@@ -35,8 +33,8 @@
 signals:
 	void newStatusText(const QString& newStatusText);
 	void selectionChanged(const QSet<ldraw::id_t>& newSelection);
-	void mouseClick(const MouseClickInfo& info);
-	void mouseMove(const MouseMoveInfo& info);
+	void mouseClick(Canvas* canvas);
+	void mouseMove(Canvas* canvas);
 private:
 	void updateGridMatrix();
 	glm::vec3 cameraVector() const;
@@ -50,15 +48,3 @@
 	QSet<ldraw::id_t> selection;
 	OverpaintCallback overpaintCallback = nullptr;
 };
-
-struct Canvas::MouseClickInfo
-{
-	std::optional<glm::vec3> worldPosition;
-	Canvas* invoker;
-};
-
-struct Canvas::MouseMoveInfo
-{
-	std::optional<glm::vec3> worldPosition;
-	Canvas* invoker;
-};

mercurial