begin model rework

Wed, 14 Feb 2018 15:17:30 +0200

author
Santeri Piippo
date
Wed, 14 Feb 2018 15:17:30 +0200
changeset 1244
68e126e8c629
parent 1243
0fb1d3d17b60
child 1245
338d66111168

begin model rework

src/format.h file | annotate | diff | comparison | revisions
src/glcompiler.cpp file | annotate | diff | comparison | revisions
src/glcompiler.h file | annotate | diff | comparison | revisions
src/glrenderer.cpp file | annotate | diff | comparison | revisions
src/glrenderer.h file | annotate | diff | comparison | revisions
src/lddocument.h file | annotate | diff | comparison | revisions
src/linetypes/modelobject.h file | annotate | diff | comparison | revisions
src/mainwindow.cpp file | annotate | diff | comparison | revisions
src/model.cpp file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
--- a/src/format.h	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/format.h	Wed Feb 14 15:17:30 2018 +0200
@@ -19,6 +19,7 @@
 #pragma once
 #include <QIODevice>
 #include <QGenericMatrix>
+#include <QModelIndex>
 #include "basics.h"
 #include "colors.h"
 #include "types/matrix.h"
@@ -87,6 +88,11 @@
 		m_text += "}";
 	}
 
+	StringFormatArg(const QModelIndex& index)
+	{
+		m_text = QString("{%1, %2}").arg(index.row(), index.column());
+	}
+
 	inline QString text() const
 	{
 		return m_text;
--- a/src/glcompiler.cpp	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/glcompiler.cpp	Wed Feb 14 15:17:30 2018 +0200
@@ -77,8 +77,11 @@
 	connect(renderer, SIGNAL(objectHighlightingChanged(LDObject*)), this, SLOT(compileObject(LDObject*)));
 	connect(m_window, SIGNAL(gridChanged()), this, SLOT(recompile()));
 
-	for (LDObject* object : renderer->model()->objects())
-		stageForCompilation(object);
+	for (QModelIndex index : renderer->model()->indices())
+	{
+		print("%1", index);
+		stageForCompilation(index);
+	}
 }
 
 /*
@@ -228,17 +231,22 @@
 /*
  * Stages the given object for compilation.
  */
-void GLCompiler::stageForCompilation(LDObject* obj)
+void GLCompiler::stageForCompilation(QModelIndex index)
 {
-	m_staged << obj;
+	m_staged.insert(index);
 }
 
 /*
  * Removes an object from the set of objects to be compiled.
  */
-void GLCompiler::unstage(LDObject* obj)
+void GLCompiler::unstage(QModelIndex index)
 {
-	m_staged.remove (obj);
+	m_staged.remove(index);
+}
+
+LDObject* GLCompiler::resolveObject(const QModelIndex& index)
+{
+	return m_renderer->model()->data(index, Model::ObjectRole).value<LDObject*>();
 }
 
 /*
@@ -246,8 +254,8 @@
  */
 void GLCompiler::compileStaged()
 {
-	for (LDObject* object : m_staged)
-		compileObject(object);
+	for (const QModelIndex& index : m_staged)
+		compileObject(index);
 
 	m_staged.clear();
 }
@@ -265,18 +273,21 @@
 		// Merge the VBO into a vector of floats.
 		QVector<GLfloat> vbodata;
 
-		for (auto it = m_objectInfo.begin(); it != m_objectInfo.end();)
-		{
-			if (it.key() == nullptr)
+		for (
+			auto iterator = m_objectInfo.begin();
+			iterator != m_objectInfo.end();
+		) {
+			if (not iterator.key().isValid())
 			{
-				it = m_objectInfo.erase(it);
+				iterator = m_objectInfo.erase(iterator);
 			}
 			else
 			{
-				if (not it.key()->isHidden())
-					vbodata += it->data[vbonum];
+				LDObject* object = resolveObject(iterator.key());
+				if (not object->isHidden())
+					vbodata += iterator->data[vbonum];
 
-				++it;
+				++iterator;
 			}
 		}
 
@@ -293,12 +304,13 @@
 /*
  * Removes the data related to the given object.
  */
-void GLCompiler::dropObjectInfo(LDObject* object)
+void GLCompiler::dropObjectInfo(const QModelIndex& index)
 {
-	if (m_objectInfo.contains(object))
+	if (m_objectInfo.contains(index))
 	{
-		// If we have data relating to this object, remove it. The VBOs have changed now and need to be merged.
-		m_objectInfo.remove(object);
+		// If we have data relating to this object, remove it.
+		// The VBOs have changed now and need to be merged.
+		m_objectInfo.remove(index);
 		needMerge();
 	}
 }
@@ -306,27 +318,29 @@
 /*
  * Makes the compiler forget about the given object completely.
  */
-void GLCompiler::forgetObject(LDObject* object)
+void GLCompiler::forgetObject(QModelIndex index)
 {
-	dropObjectInfo(object);
-	unstage(object);
+	dropObjectInfo(index);
+	unstage(index);
 }
 
 /*
  * Compiles a single object.
  */
-void GLCompiler::compileObject(LDObject* object)
+void GLCompiler::compileObject(QModelIndex index)
 {
+	LDObject* object = resolveObject(index);
+
 	if (object == nullptr)
 		return;
 
 	ObjectVboData info;
-	dropObjectInfo(object);
+	dropObjectInfo(index);
 
 	switch (object->type())
 	{
-	// Note: We cannot split quads into triangles here, it would mess up the wireframe view.
-	// Quads must go into separate vbos.
+	// Note: We cannot split quads into triangles here, it would mess up the
+	// wireframe view. Quads must go into separate vbos.
 	case LDObjectType::Triangle:
 	case LDObjectType::Quadrilateral:
 	case LDObjectType::EdgeLine:
@@ -368,7 +382,7 @@
 		break;
 	}
 
-	m_objectInfo[object] = info;
+	m_objectInfo[index] = info;
 	needMerge();
 }
 
@@ -461,6 +475,6 @@
  */
 void GLCompiler::recompile()
 {
-	for (LDObject* object : m_renderer->model()->objects())
-		compileObject(object);
+	for (QModelIndex index : m_renderer->model()->indices())
+		compileObject(index);
 }
--- a/src/glcompiler.h	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/glcompiler.h	Wed Feb 14 15:17:30 2018 +0200
@@ -49,18 +49,19 @@
 
 	void compileStaged();
 	void compilePolygon (LDPolygon& poly, LDObject* polygonOwner, ObjectVboData& objectInfo);
-	Q_SLOT void compileObject (LDObject* obj);
+	Q_SLOT void compileObject (QModelIndex index);
 	QColor getColorForPolygon (LDPolygon& poly, LDObject* topobj, VboSubclass complement);
 	QColor indexColorForID (qint32 id) const;
 	void needMerge();
 	Q_SLOT void recompile();
-	void dropObjectInfo (LDObject* obj);
-	Q_SLOT void forgetObject(LDObject* object);
-	void stageForCompilation (LDObject* obj);
-	void unstage (LDObject* obj);
+	void dropObjectInfo (const QModelIndex &index);
+	Q_SLOT void forgetObject(QModelIndex index);
+	void stageForCompilation(QModelIndex index);
+	void unstage (QModelIndex index);
+	LDObject* resolveObject(const QModelIndex& index);
 
-	QMap<LDObject*, ObjectVboData>	m_objectInfo;
-	QSet<LDObject*> m_staged; // Objects that need to be compiled
+	QMap<QPersistentModelIndex, ObjectVboData> m_objectInfo;
+	QSet<QPersistentModelIndex> m_staged; // Objects that need to be compiled
 	GLuint m_vbo[NumVbos];
 	bool m_vboChanged[NumVbos] = {true};
 	int m_vboSizes[NumVbos] = {0};
--- a/src/glrenderer.cpp	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/glrenderer.cpp	Wed Feb 14 15:17:30 2018 +0200
@@ -1035,3 +1035,8 @@
  * before the main brick is rendered.
  */
 void GLRenderer::drawFixedCameraBackdrop() {}
+
+void GLRenderer::setSelection(const QItemSelection& selection)
+{
+	this->m_selectedItems = selection;
+}
--- a/src/glrenderer.h	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/glrenderer.h	Wed Feb 14 15:17:30 2018 +0200
@@ -72,6 +72,7 @@
 	void setBackground();
 	void setCamera(Camera cam);
 	QPen textPen() const;
+	void setSelection(const QItemSelection& selection);
 
 	static const QPen thinBorderPen;
 	static const GLRotationMatrix topCameraMatrix;
@@ -140,6 +141,7 @@
 	QColor m_backgroundColor;
 	GLuint m_axesVbo;
 	GLuint m_axesColorVbo;
+	QItemSelection m_selectedItems;
 
 	void calcCameraIcons();
 	void drawGLScene();
--- a/src/lddocument.h	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/lddocument.h	Wed Feb 14 15:17:30 2018 +0200
@@ -62,7 +62,7 @@
 	void inlineContents(Model& model, bool deep, bool renderinline);
 	QList<LDPolygon> inlinePolygons();
 	const QSet<Vertex>& inlineVertices();
-	void insertObject (int pos, LDObject* obj);
+	void insertObject (int pos, LDObject* obj) __attribute__((deprecated));
 	bool isFrozen() const;
 	bool isSafeToClose();
 	QString name() const;
--- a/src/linetypes/modelobject.h	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/linetypes/modelobject.h	Wed Feb 14 15:17:30 2018 +0200
@@ -115,6 +115,8 @@
 	Vertex m_coords[4];
 };
 
+Q_DECLARE_METATYPE(LDObject*)
+
 /*
  * Base class for objects with matrices.
  */
--- a/src/mainwindow.cpp	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/mainwindow.cpp	Wed Feb 14 15:17:30 2018 +0200
@@ -74,6 +74,10 @@
 	connect (m_tabs, SIGNAL (currentChanged(int)), this, SLOT (tabSelected()));
 	connect (m_tabs, SIGNAL (tabCloseRequested (int)), this, SLOT (closeTab (int)));
 	connect(m_documents, SIGNAL(documentClosed(LDDocument*)), this, SLOT(documentClosed(LDDocument*)));
+	connect(
+		ui.objectList->selectionModel(), SIGNAL(selectionChanged()),
+		this, SLOT(selectionChanged())
+	);
 
 	if (m_primitives->activeScanner())
 		connect (m_primitives->activeScanner(), SIGNAL (workDone()), this, SLOT (updatePrimitives()));
--- a/src/model.cpp	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/model.cpp	Wed Feb 14 15:17:30 2018 +0200
@@ -525,6 +525,11 @@
 		return nullptr;
 }
 
+IndexGenerator Model::indices() const
+{
+	return {this};
+}
+
 int Model::rowCount(const QModelIndex&) const
 {
 	return this->objects().size();
@@ -532,6 +537,9 @@
 
 QVariant Model::data(const QModelIndex& index, int role) const
 {
+	if (index.row() < 0 or index.row() >= size())
+		return {};
+
 	LDObject* object = this->objects()[index.row()];
 
 	switch (role)
@@ -566,7 +574,8 @@
 			and object->color() != MainColor
 			and object->color() != EdgeColor
 		) {
-			// If the object isn't in the main or edge color, draw this list entry in that color.
+			// If the object isn't in the main or edge color, draw this list
+			// entry in that color.
 			return object->color().faceColor();
 		}
 		else
@@ -586,11 +595,32 @@
 			return {};
 		}
 
+	case ObjectRole:
+		return {qMetaTypeId<LDObject*>(), object};
+
 	default:
 		return {};
 	}
 }
 
+bool Model::removeRows(int row, int count, const QModelIndex& parent)
+{
+	if (row >= 0 and row < size() and count <= size() - row)
+	{
+		beginRemoveRows(parent, row, row + count - 1);
+
+		for (signed int i = row + count - 1; i >= row; i -= 1)
+			this->removeAt(i);
+
+		endRemoveRows();
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
 int countof(Model& model)
 {
 	return model.size();
--- a/src/model.h	Tue Feb 13 15:43:55 2018 +0200
+++ b/src/model.h	Wed Feb 14 15:17:30 2018 +0200
@@ -21,6 +21,54 @@
 #include "main.h"
 #include "linetypes/modelobject.h"
 
+class IndexGenerator
+{
+	class Iterator
+	{
+	public:
+		Iterator(const QAbstractListModel* model, int row) :
+			model {model},
+			row {row} {}
+
+		Iterator& operator++()
+		{
+			this->row += 1;
+			return *this;
+		}
+
+		QModelIndex operator*() const
+		{
+			return this->model->index(this->row);
+		}
+
+		bool operator!=(const Iterator& other)
+		{
+			return this->row != other.row or this->model != other.model;
+		}
+
+	private:
+		const QAbstractListModel* model;
+		int row;
+	};
+
+public:
+	IndexGenerator(const QAbstractListModel* model) :
+		model {model} {}
+
+	Iterator begin() const
+	{
+		return {this->model, 0};
+	}
+
+	Iterator end() const
+	{
+		return {this->model, this->model->rowCount()};
+	}
+
+private:
+	const QAbstractListModel* model;
+};
+
 /*
  * This class represents a LDraw model, consisting of a vector of objects. It manages LDObject ownership.
  */
@@ -29,6 +77,11 @@
 	Q_OBJECT
 
 public:
+	enum
+	{
+		ObjectRole = Qt::UserRole
+	};
+
 	Model(class DocumentManager* manager);
 	Model(const Model& other) = delete;
 	~Model();
@@ -58,9 +111,11 @@
 	LDObject* insertFromString(int position, QString line);
 	LDObject* addFromString(QString line);
 	LDObject* replaceWithFromString(LDObject* object, QString line);
+	IndexGenerator indices() const;
 
 	int rowCount(const QModelIndex& parent) const override;
 	QVariant data(const QModelIndex& index, int role) const override;
+	bool removeRows(int row, int count, const QModelIndex& ) override;
 
 signals:
 	void objectAdded(LDObject* object);

mercurial