From 993e9dbd15b51a7301bd8e6f9633bf157585669e Mon Sep 17 00:00:00 2001
From: Matthias Puchner <github@mpuchner.de>
Date: Fri, 10 Dec 2021 15:21:57 +0100
Subject: [PATCH] free RealSpacePanel/RealSpaceCanvas from
 SessionItem/SessionModel knowledge

---
 GUI/View/Realspace/RealSpaceCanvas.cpp     | 62 +++++-----------------
 GUI/View/Realspace/RealSpaceCanvas.h       | 20 +++----
 GUI/View/SampleDesigner/RealSpacePanel.cpp |  5 +-
 GUI/View/SampleDesigner/RealSpacePanel.h   |  6 +--
 GUI/View/SampleDesigner/SampleView.cpp     |  3 +-
 5 files changed, 24 insertions(+), 72 deletions(-)

diff --git a/GUI/View/Realspace/RealSpaceCanvas.cpp b/GUI/View/Realspace/RealSpaceCanvas.cpp
index 0f2593d9739..2c2a6439ea5 100644
--- a/GUI/View/Realspace/RealSpaceCanvas.cpp
+++ b/GUI/View/Realspace/RealSpaceCanvas.cpp
@@ -14,9 +14,6 @@
 
 #include "GUI/View/Realspace/RealSpaceCanvas.h"
 #include "GUI/Application/ApplicationSettings.h"
-#include "GUI/Model/Group/FilterPropertyProxy.h"
-#include "GUI/Model/Sample/SampleModel.h"
-#include "GUI/Model/Session/SessionItemUtils.h"
 #include "GUI/Model/State/SessionData.h"
 #include "GUI/View/Info/CautionSign.h"
 #include "GUI/View/Realspace/RealSpaceBuilder.h"
@@ -28,14 +25,11 @@
 #include <QVBoxLayout>
 #include <memory>
 
-RealSpaceCanvas::RealSpaceCanvas(const MaterialModel* materialModel, SampleModel* sampleModel,
-                                 QWidget* parent)
+RealSpaceCanvas::RealSpaceCanvas(const MaterialModel* materialModel, QWidget* parent)
     : QWidget(parent)
-    , m_sampleModel(sampleModel)
     , m_materialModel(materialModel)
     , m_view(new GUI::RealSpace::Canvas)
     , m_cautionSign(new CautionSign(this))
-    , m_currentItem(nullptr)
     , m_firstView(true)
 {
     auto* layout = new QVBoxLayout;
@@ -45,17 +39,22 @@ RealSpaceCanvas::RealSpaceCanvas(const MaterialModel* materialModel, SampleModel
     setLayout(layout);
 }
 
-void RealSpaceCanvas::setCurrentItem(SessionItem* item)
+void RealSpaceCanvas::setCurrentItem(SampleItem item)
 {
     m_currentItem = item;
     updateScene();
     defaultView(); // Enforces default view and also sets the zoomLevel to default i.e. 0
 }
 
+std::optional<SampleItem> RealSpaceCanvas::currentItem() const
+{
+    return m_currentItem;
+}
+
 void RealSpaceCanvas::changeLayerSize(double layerSizeChangeScale)
 {
     // when no object is selected --> take no action
-    if (m_currentItem == nullptr)
+    if (!m_currentItem)
         return;
 
     m_sceneGeometry.layerSize = m_sceneGeometry.layerSize * layerSizeChangeScale;
@@ -69,31 +68,14 @@ void RealSpaceCanvas::savePicture()
     savePicture(pixmap);
 }
 
-void RealSpaceCanvas::onRowsAboutToBeRemoved(const QModelIndex& parent, int first, int)
-{
-    // clear scene if current selection will be removed
-    if (!m_sampleModel)
-        return;
-    const QModelIndex idx = m_sampleModel->index(first, 0, parent);
-    const auto* itemToBeRemoved = m_sampleModel->itemForIndex(idx);
-    if (m_currentItem == itemToBeRemoved)
-        resetScene();
-}
-
 void RealSpaceCanvas::showEvent(QShowEvent*)
 {
-    setConnected(m_sampleModel, true);
     updateScene();
     if (m_firstView)
         m_view->defaultView();
     m_firstView = false;
 }
 
-void RealSpaceCanvas::hideEvent(QHideEvent*)
-{
-    setConnected(m_sampleModel, false);
-}
-
 void RealSpaceCanvas::savePicture(const QPixmap& pixmap)
 {
     QString dirname = gSessionData->projectDocument->userExportDir();
@@ -122,6 +104,9 @@ void RealSpaceCanvas::savePicture(const QPixmap& pixmap)
 
 void RealSpaceCanvas::updateScene()
 {
+    if (isHidden()) // to improve performance
+        return;
+
     if (!m_view->isValid()) // GL not initialized (widget not shown so far) -> no updating possible
         return;
 
@@ -134,7 +119,7 @@ void RealSpaceCanvas::updateScene()
     try {
         m_cautionSign->clear();
         if (m_currentItem)
-            builder3D.populate(m_realSpaceModel.get(), m_currentItem, m_sceneGeometry,
+            builder3D.populate(m_realSpaceModel.get(), *m_currentItem, m_sceneGeometry,
                                m_view->cam()->getPos());
     } catch (const std::exception& ex) {
         m_cautionSign->setCautionMessage(ex.what());
@@ -167,26 +152,3 @@ void RealSpaceCanvas::topView()
 {
     m_view->topView();
 }
-
-void RealSpaceCanvas::setConnected(SampleModel* model, bool makeConnected)
-{
-    if (!model)
-        return;
-
-    if (makeConnected) {
-        connect(model, &SampleModel::rowsInserted, this, &RealSpaceCanvas::updateScene,
-                Qt::UniqueConnection);
-        connect(model, &SampleModel::rowsRemoved, this, &RealSpaceCanvas::updateScene,
-                Qt::UniqueConnection);
-        connect(model, &SampleModel::rowsAboutToBeRemoved, this,
-                &RealSpaceCanvas::onRowsAboutToBeRemoved, Qt::UniqueConnection);
-        connect(model, &SampleModel::itemDataChanged, this, &RealSpaceCanvas::updateScene,
-                Qt::UniqueConnection);
-        connect(model, &SampleModel::modelReset, this, &RealSpaceCanvas::resetScene,
-                Qt::UniqueConnection);
-        connect(
-            model, &SampleModel::modelAboutToBeReset, this, [&]() { m_currentItem = nullptr; },
-            Qt::UniqueConnection);
-    } else
-        model->disconnect(this);
-}
diff --git a/GUI/View/Realspace/RealSpaceCanvas.h b/GUI/View/Realspace/RealSpaceCanvas.h
index a1d1f764f84..5444313ca52 100644
--- a/GUI/View/Realspace/RealSpaceCanvas.h
+++ b/GUI/View/Realspace/RealSpaceCanvas.h
@@ -15,12 +15,12 @@
 #ifndef BORNAGAIN_GUI_VIEW_REALSPACE_REALSPACECANVAS_H
 #define BORNAGAIN_GUI_VIEW_REALSPACE_REALSPACECANVAS_H
 
+#include "GUI/Model/Sample/SampleItem.h"
 #include <QWidget>
 #include <memory>
+#include <optional>
 
-class SampleModel;
 class CautionSign;
-class SessionItem;
 class MaterialModel;
 namespace GUI::RealSpace {
 
@@ -41,34 +41,30 @@ class RealSpaceCanvas : public QWidget {
     Q_OBJECT
 
 public:
-    RealSpaceCanvas(const MaterialModel* materialModel, SampleModel* sampleModel,
-                    QWidget* parent = nullptr);
+    RealSpaceCanvas(const MaterialModel* materialModel, QWidget* parent = nullptr);
 
-    void setCurrentItem(SessionItem* item);
+    void setCurrentItem(SampleItem item);
+    std::optional<SampleItem> currentItem() const;
     void defaultView();
     void sideView();
     void topView();
     void changeLayerSize(double layerSizeChangeScale);
     void savePicture();
+    void resetScene();
+    void updateScene();
 
 protected:
     void showEvent(QShowEvent*) override;
-    void hideEvent(QHideEvent*) override;
 
 private:
-    void updateScene();
-    void resetScene();
-    void onRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last);
-    void setConnected(SampleModel* model, bool makeConnected);
     void savePicture(const QPixmap& pixmap);
 
-    SampleModel* m_sampleModel;
     const MaterialModel* m_materialModel;
     GUI::RealSpace::Canvas* m_view;
     std::unique_ptr<GUI::RealSpace::Model> m_realSpaceModel;
     SceneGeometry m_sceneGeometry;
     CautionSign* m_cautionSign;
-    SessionItem* m_currentItem;
+    std::optional<SampleItem> m_currentItem;
     bool m_firstView;
 };
 
diff --git a/GUI/View/SampleDesigner/RealSpacePanel.cpp b/GUI/View/SampleDesigner/RealSpacePanel.cpp
index 602572372cd..374e5680a4f 100644
--- a/GUI/View/SampleDesigner/RealSpacePanel.cpp
+++ b/GUI/View/SampleDesigner/RealSpacePanel.cpp
@@ -17,9 +17,8 @@
 #include "GUI/View/Realspace/RealSpaceCanvas.h"
 #include <QVBoxLayout>
 
-RealSpacePanel::RealSpacePanel(const MaterialModel* materialModel, SampleModel* sampleModel,
-                               QWidget* parent)
-    : QWidget(parent), m_canvas(new RealSpaceCanvas(materialModel, sampleModel))
+RealSpacePanel::RealSpacePanel(const MaterialModel* materialModel, QWidget* parent)
+    : QWidget(parent), m_canvas(new RealSpaceCanvas(materialModel))
 {
     setWindowTitle("Real Space");
 
diff --git a/GUI/View/SampleDesigner/RealSpacePanel.h b/GUI/View/SampleDesigner/RealSpacePanel.h
index 7cedc7f00f7..594bf5af2a0 100644
--- a/GUI/View/SampleDesigner/RealSpacePanel.h
+++ b/GUI/View/SampleDesigner/RealSpacePanel.h
@@ -17,11 +17,7 @@
 
 #include <QWidget>
 
-class SampleModel;
-class QItemSelectionModel;
 class RealSpaceCanvas;
-class QAction;
-class QToolBar;
 class MaterialModel;
 
 //! Panel to show 3D view of sample. Contains toolbar and RealSpaceCanvas
@@ -30,7 +26,7 @@ class RealSpacePanel : public QWidget {
     Q_OBJECT
 
 public:
-    RealSpacePanel(const MaterialModel* materialModel, SampleModel* sampleModel, QWidget* parent);
+    RealSpacePanel(const MaterialModel* materialModel, QWidget* parent);
 
     QSize sizeHint() const override;
     RealSpaceCanvas* canvas();
diff --git a/GUI/View/SampleDesigner/SampleView.cpp b/GUI/View/SampleDesigner/SampleView.cpp
index b200bca50b6..a1013e3540a 100644
--- a/GUI/View/SampleDesigner/SampleView.cpp
+++ b/GUI/View/SampleDesigner/SampleView.cpp
@@ -64,8 +64,7 @@ SampleView::SampleView(QWidget* parent, ProjectDocument* document)
                                        QSizePolicy::MinimumExpanding);
 
     auto* scriptPanel = new ScriptPanel(m_document->sampleModel(), this);
-    m_realSpacePanel =
-        new RealSpacePanel(m_document->materialModel(), m_document->sampleModel(), this);
+    m_realSpacePanel = new RealSpacePanel(m_document->materialModel(), this);
 
     sampleSelectionPane->setWindowTitle("Samples");
 
-- 
GitLab