Made a new renderer be created for each document, instead of reusing the same renderer for all documents.

Thu, 09 Feb 2017 00:32:24 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Thu, 09 Feb 2017 00:32:24 +0200
changeset 1097
9a9e6ce0c5dc
parent 1096
7cc929d8fc4d
child 1098
0b837bed121d

Made a new renderer be created for each document, instead of reusing the same renderer for all documents.

src/documentmanager.cpp file | annotate | diff | comparison | revisions
src/documentmanager.h file | annotate | diff | comparison | revisions
src/glRenderer.cpp file | annotate | diff | comparison | revisions
src/glRenderer.h file | annotate | diff | comparison | revisions
src/hierarchyelement.cpp file | annotate | diff | comparison | revisions
src/ldDocument.cpp 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/messageLog.cpp file | annotate | diff | comparison | revisions
src/messageLog.h file | annotate | diff | comparison | revisions
--- a/src/documentmanager.cpp	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/documentmanager.cpp	Thu Feb 09 00:32:24 2017 +0200
@@ -346,7 +346,6 @@
 	if (m_loadingMainFile)
 	{
 		m_window->changeDocument (load);
-		m_window->renderer()->setDocument (load);
 		print (tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings);
 	}
 
--- a/src/documentmanager.h	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/documentmanager.h	Thu Feb 09 00:32:24 2017 +0200
@@ -49,6 +49,9 @@
 	void openMainModel (QString path);
 	bool preInline (LDDocument* doc, Model& model, bool deep, bool renderinline);
 
+signals:
+	void documentClosed(LDDocument* document);
+
 private:
 	Documents m_documents;
 	bool m_loadingMainFile;
--- a/src/glRenderer.cpp	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/glRenderer.cpp	Thu Feb 09 00:32:24 2017 +0200
@@ -67,21 +67,29 @@
 
 // =============================================================================
 //
-GLRenderer::GLRenderer (QWidget* parent) :
-	QGLWidget (parent),
-	HierarchyElement (parent)
+GLRenderer::GLRenderer(LDDocument* document, QWidget* parent) :
+    QGLWidget {parent},
+    HierarchyElement {parent},
+    m_document {document}
 {
 	m_camera = (Camera) m_config->camera();
 	m_currentEditMode = AbstractEditMode::createByType (this, EditModeType::Select);
 	m_compiler = new GLCompiler (this);
-	m_messageLog = new MessageManager (this);
-	m_messageLog->setRenderer (this);
 	m_toolTipTimer = new QTimer (this);
 	m_toolTipTimer->setSingleShot (true);
 	m_thinBorderPen = QPen (QColor (0, 0, 0, 208), 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
 	m_thinBorderPen.setWidth (1);
 	setAcceptDrops (true);
 	connect (m_toolTipTimer, SIGNAL (timeout()), this, SLOT (slot_toolTipTimer()));
+	initOverlaysFromObjects();
+
+	if (not currentDocumentData().init)
+	{
+		resetAllAngles();
+		currentDocumentData().init = true;
+	}
+
+	currentDocumentData().needZoomToFit = true;
 
 	// Init camera icons
 	for (Camera camera : iterateEnum<Camera>())
@@ -105,9 +113,6 @@
 //
 GLRenderer::~GLRenderer()
 {
-	if (messageLog())
-		messageLog()->setRenderer (nullptr);
-
 	m_compiler->setRenderer (nullptr);
 	delete m_compiler;
 	delete m_currentEditMode;
@@ -178,11 +183,6 @@
 	m_isDrawOnly = value;
 }
 
-MessageManager* GLRenderer::messageLog() const
-{
-	return m_messageLog;
-}
-
 LDDocument* GLRenderer::document() const
 {
 	return m_document;
@@ -682,13 +682,13 @@
 	}
 
 	// Message log
-	if (messageLog())
+	if (m_window->messageLog())
 	{
 		int y = 0;
 		int margin = 2;
 		QColor penColor = textPen().color();
 
-		for (const MessageManager::Line& line : messageLog()->getLines())
+		for (const MessageManager::Line& line : m_window->messageLog()->getLines())
 		{
 			penColor.setAlphaF(line.alpha);
 			painter.setPen(penColor);
@@ -880,7 +880,6 @@
 	{
 		m_camera = camera;
 		m_config->setCamera(int {camera});
-		m_window->updateEditModeActions();
 	}
 }
 
@@ -1023,26 +1022,6 @@
 
 // =============================================================================
 //
-void GLRenderer::setDocument (LDDocument* document)
-{
-	m_document = document;
-
-	if (document)
-	{
-		initOverlaysFromObjects();
-
-		if (not currentDocumentData().init)
-		{
-			resetAllAngles();
-			currentDocumentData().init = true;
-		}
-
-		currentDocumentData().needZoomToFit = true;
-	}
-}
-
-// =============================================================================
-//
 void GLRenderer::setPicking(bool value)
 {
 	m_isDrawingSelectionScene = value;
--- a/src/glRenderer.h	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/glRenderer.h	Thu Feb 09 00:32:24 2017 +0200
@@ -126,7 +126,7 @@
 	Q_OBJECT
 
 public:
-	GLRenderer (QWidget* parent = nullptr);
+	GLRenderer(LDDocument* document, QWidget* parent = nullptr);
 	~GLRenderer();
 
 	Camera camera() const;
@@ -161,7 +161,6 @@
 	Qt::KeyboardModifiers keyboardModifiers() const;
 	QPen linePen() const;
 	void makeCurrent();
-	MessageManager* messageLog() const;
 	bool mouseHasMoved() const;
 	QPoint const& mousePosition() const;
 	QPointF const& mousePositionF() const;
@@ -177,7 +176,6 @@
 	void setBackground();
 	void setCamera(Camera cam);
 	void setDepthValue(double depth);
-	void setDocument(LDDocument* document);
 	void setDrawOnly(bool value);
 	void setEditMode(EditModeType type);
 	void setPicking(bool a);
@@ -203,7 +201,6 @@
 	void wheelEvent(QWheelEvent* ev);
 
 private:
-	MessageManager* m_messageLog = nullptr;
 	LDDocument* m_document = nullptr;
 	GLCompiler* m_compiler;
 	LDObject* m_objectAtCursor = nullptr;
--- a/src/hierarchyelement.cpp	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/hierarchyelement.cpp	Thu Feb 09 00:32:24 2017 +0200
@@ -38,7 +38,8 @@
 		// Drat! It doesn't seem to have the MainWindow as a parent! We'll need to force it to be in one.
 		// This shouldn't have any side effects but also shouldn't happen regardless.
 		m_window = g_win;
-		print("Hierarchy element instance %1 should be in the hierarchy of a MainWindow, but isn't.\n", this);
+		print("Hierarchy element instance %1 should have a MainWindow parent, but it is %2 (%3).\n", this,
+		      parent, parent ? parent->metaObject()->className() : "nullptr");
 	}
 
 	m_documents = m_window->documents();
--- a/src/ldDocument.cpp	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/ldDocument.cpp	Thu Feb 09 00:32:24 2017 +0200
@@ -147,12 +147,7 @@
 	if (not isFrozen())
 	{
 		m_flags |= IsFrozen;
-		print ("Closed %1", name());
-		m_window->updateDocumentList();
-
-		// If the current document just became implicit (i.e. user closed it), we need to get a new one to show.
-		if (currentDocument() == this)
-			m_window->currentDocumentClosed();
+		m_manager->documentClosed(this);
 	}
 }
 
--- a/src/mainwindow.cpp	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/mainwindow.cpp	Thu Feb 09 00:32:24 2017 +0200
@@ -62,24 +62,25 @@
 	m_isSelectionLocked (false)
 {
 	g_win = this;
+	m_messageLog = new MessageManager {this};
 	ui.setupUi (this);
 	m_updatingTabs = false;
-	m_renderer = new GLRenderer (this);
 	m_tabs = new QTabBar;
 	m_tabs->setTabsClosable (true);
 	ui.verticalLayout->insertWidget (0, m_tabs);
 	createBlankDocument();
-	m_renderer->setDocument (m_currentDocument);
-
-	// Stuff the renderer into its frame
-	QVBoxLayout* rendererLayout = new QVBoxLayout (ui.rendererFrame);
-	rendererLayout->addWidget (renderer());
+	print("Setting current widget...");
+	GLRenderer* renderer_ = getRendererForDocument(m_currentDocument);
+	print("Choosing: %1", renderer_);
+	ui.rendererStack->setCurrentWidget(renderer_);
+	print("Set: %1", renderer());
 
 	connect (ui.objectList, SIGNAL (itemSelectionChanged()), this, SLOT (selectionChanged()));
 	connect (ui.objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this,
 			 SLOT (objectListDoubleClicked (QListWidgetItem*)));
 	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*)));
 
 	if (m_primitives->activeScanner())
 		connect (m_primitives->activeScanner(), SIGNAL (workDone()), this, SLOT (updatePrimitives()));
@@ -103,7 +104,6 @@
 	updateTitle();
 	loadShortcuts();
 	setMinimumSize (300, 200);
-	connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (doLastSecondCleanup()));
 	connect (ui.ringToolHiRes, SIGNAL (clicked (bool)), this, SLOT (ringToolHiResClicked (bool)));
 	connect (ui.ringToolSegments, SIGNAL (valueChanged (int)), this, SLOT (circleToolSegmentsChanged()));
 	circleToolSegmentsChanged(); // invoke it manually for initial label text
@@ -179,7 +179,6 @@
 	delete m_mathFunctions;
 	delete &ui;
 	delete m_settings;
-	delete m_documents;
 
 	for (Toolset* toolset : m_toolsets)
 		delete toolset;
@@ -218,14 +217,6 @@
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void MainWindow::doLastSecondCleanup()
-{
-	delete m_renderer;
-	delete &ui;
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
 void MainWindow::updateRecentFilesMenu()
 {
 	// First, clear any items in the recent files menu
@@ -514,7 +505,7 @@
 void MainWindow::doFullRefresh()
 {
 	buildObjectList();
-	m_renderer->hardRefresh();
+	renderer()->hardRefresh();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -524,7 +515,7 @@
 void MainWindow::refresh()
 {
 	buildObjectList();
-	m_renderer->update();
+	renderer()->update();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -788,10 +779,9 @@
 	return false;
 }
 
-// Adds a message to the renderer's message manager.
 void MainWindow::addMessage (QString msg)
 {
-	m_renderer->messageLog()->addLine (msg);
+	messageLog()->addLine (msg);
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -832,6 +822,11 @@
 		(QMessageBox::Close), QMessageBox::Close);
 }
 
+MessageManager* MainWindow::messageLog() const
+{
+	return m_messageLog;
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 void MainWindow::updateDocumentList()
@@ -966,7 +961,7 @@
 //
 GLRenderer* MainWindow::renderer()
 {
-	return m_renderer;
+	return static_cast<GLRenderer*>(ui.rendererStack->currentWidget());
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -1154,7 +1149,7 @@
 		print ("Opened %1", document->name());
 
 		// Cache files are not compiled by the GL renderer. Now that this file is open for editing, it needs to be compiled.
-		m_renderer->compiler()->compileDocument(document);
+		getRendererForDocument(document)->compiler()->compileDocument(document);
 		updateDocumentList();
 	}
 }
@@ -1177,6 +1172,8 @@
 		return;
 
 	m_currentDocument = document;
+	GLRenderer* renderer = getRendererForDocument(document);
+	ui.rendererStack->setCurrentWidget(renderer);
 
 	if (document)
 	{
@@ -1184,12 +1181,50 @@
 		updateDocumentListItem (document);
 		buildObjectList();
 		updateTitle();
-		m_renderer->setDocument (document);
-		m_renderer->compiler()->needMerge();
 		print ("Changed document to %1", document->getDisplayName());
 	}
 }
 
+/*
+ * Returns the associated renderer for the given document
+ */
+GLRenderer* MainWindow::getRendererForDocument(LDDocument *document)
+{
+	GLRenderer* renderer = m_renderers.value(document);
+
+	if (not renderer)
+	{
+		print("MainWindow: Couldn't find a renderer for %1, creating one now", document->getDisplayName());
+		renderer = new GLRenderer {document, this};
+		print("Created renderer: %1", renderer);
+		m_renderers[document] = renderer;
+		ui.rendererStack->addWidget(renderer);
+		connect(m_messageLog, SIGNAL(changed()), renderer, SLOT(update()));
+	}
+
+	return renderer;
+}
+
+void MainWindow::documentClosed(LDDocument *document)
+{
+	print ("Closed %1", document->name());
+	updateDocumentList();
+
+	// If the current document just became implicit (i.e. user closed it), we need to get a new one to show.
+	if (currentDocument() == document)
+		currentDocumentClosed();
+
+	GLRenderer* renderer = m_renderers.value(document);
+
+	if (renderer)
+	{
+		ui.rendererStack->removeWidget(renderer);
+		renderer->deleteLater();
+	}
+
+	m_renderers.remove(document);
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 // This little beauty closes the initial file that was open at first when opening a new file over it.
--- a/src/mainwindow.h	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/mainwindow.h	Thu Feb 09 00:32:24 2017 +0200
@@ -87,10 +87,12 @@
 	QTreeWidget* getPrimitivesTree() const;
 	class QSettings* getSettings() { return m_settings; }
 	LDColor getUniformSelectedColor();
+	GLRenderer* getRendererForDocument(LDDocument* document);
 	Grid* grid();
 	class GuiUtilities* guiUtilities();
 	void loadShortcuts();
 	MathFunctions* mathFunctions() const;
+	MessageManager* messageLog() const;
 	LDDocument* newDocument (bool cache = false);
 	void openDocumentForEditing(LDDocument* document);
 	PrimitiveManager* primitives();
@@ -125,6 +127,7 @@
 	void ringToolHiResClicked (bool clicked);
 	void tabSelected();
 	void updatePrimitives();
+	void documentClosed(LDDocument* document);
 
 protected:
 	void closeEvent (QCloseEvent* ev);
@@ -134,7 +137,8 @@
 
 	Configuration& m_config;
 	class GuiUtilities* m_guiUtilities;
-	GLRenderer* m_renderer;
+	MessageManager* m_messageLog = nullptr;
+	QMap<LDDocument*, GLRenderer*> m_renderers;
 	PrimitiveManager* m_primitives;
 	Grid* m_grid;
 	MathFunctions* m_mathFunctions;
@@ -160,7 +164,6 @@
 	void selectionChanged();
 	void recentFileClicked();
 	void quickColorClicked();
-	void doLastSecondCleanup();
 	void objectListDoubleClicked (QListWidgetItem* listitem);
 };
 
--- a/src/mainwindow.ui	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/mainwindow.ui	Thu Feb 09 00:32:24 2017 +0200
@@ -20,9 +20,9 @@
   <widget class="QWidget" name="centralwidget">
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
-     <layout class="QHBoxLayout" name="horizontalLayout" stretch="3,1">
+     <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
       <item>
-       <widget class="QFrame" name="rendererFrame">
+       <widget class="QStackedWidget" name="rendererStack">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
           <horstretch>0</horstretch>
@@ -47,7 +47,7 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>233</width>
+           <width>465</width>
            <height>429</height>
           </rect>
          </property>
@@ -75,7 +75,7 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>233</width>
+           <width>465</width>
            <height>429</height>
           </rect>
          </property>
@@ -157,7 +157,7 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>233</width>
+           <width>465</width>
            <height>429</height>
           </rect>
          </property>
--- a/src/messageLog.cpp	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/messageLog.cpp	Thu Feb 09 00:32:24 2017 +0200
@@ -31,8 +31,8 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-MessageManager::MessageManager (QObject* parent) :
-	QObject (parent)
+MessageManager::MessageManager(QObject* parent) :
+    QObject {parent}
 {
 	m_ticker = new QTimer;
 	m_ticker->start (100);
@@ -81,11 +81,8 @@
 	while (countof(m_lines) >= MaxMessages)
 		m_lines.removeFirst();
 
-	m_lines << Line (line);
-
-	// Update the renderer view
-	if (renderer())
-		renderer()->update();
+	m_lines.append(Line {line});
+	emit changed();
 }
 
 // -------------------------------------------------------------------------------------------------
@@ -110,8 +107,8 @@
 		changed |= lineChanged;
 	}
 
-	if (changed and renderer())
-		renderer()->update();
+	if (changed and parent())
+		emit this->changed();
 }
 
 // =============================================================================
@@ -121,16 +118,6 @@
 	return m_lines;
 }
 
-GLRenderer* MessageManager::renderer() const
-{
-	return m_renderer;
-}
-
-void MessageManager::setRenderer (GLRenderer* renderer)
-{
-	m_renderer = renderer;
-}
-
 // =============================================================================
 //
 void printToLog (const QString& msg)
--- a/src/messageLog.h	Wed Feb 08 17:07:19 2017 +0200
+++ b/src/messageLog.h	Thu Feb 09 00:32:24 2017 +0200
@@ -62,7 +62,7 @@
 	};
 
 	// Constructs the message manager.
-	explicit MessageManager (QObject* parent = nullptr);
+	explicit MessageManager(QObject* parent = nullptr);
 
 	// Adds a line with the given \c text to the message manager.
 	void addLine (QString line);
@@ -70,13 +70,12 @@
 	// Returns all active lines in the message manager.
 	const QList<Line>& getLines() const;
 
-	GLRenderer* renderer() const;
-	void setRenderer (GLRenderer* renderer);
+signals:
+	void changed();
 
 private:
 	QList<Line> m_lines;
 	QTimer* m_ticker;
-	GLRenderer* m_renderer;
 
 private slots:
 	void tick();

mercurial