From 598e74242e98fd07c861e028646c4c0adccb04e3 Mon Sep 17 00:00:00 2001
From: Matthias Puchner <github@mpuchner.de>
Date: Wed, 13 Oct 2021 12:28:38 +0200
Subject: [PATCH] use SelectionDescriptor in ParticleLayoutItem

---
 GUI/Models/DomainObjectBuilder.cpp            |  2 +-
 GUI/Models/ParticleLayoutItem.cpp             | 43 ++++++++++++++++++-
 GUI/Models/ParticleLayoutItem.h               |  3 +-
 .../RealSpaceWidgets/RealSpaceBuilder.cpp     |  2 +-
 4 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/GUI/Models/DomainObjectBuilder.cpp b/GUI/Models/DomainObjectBuilder.cpp
index 60d69e09415..4fdf0e22f15 100644
--- a/GUI/Models/DomainObjectBuilder.cpp
+++ b/GUI/Models/DomainObjectBuilder.cpp
@@ -65,7 +65,7 @@ GUI::Model::DomainObjectBuilder::buildParticleLayout(const ParticleLayoutItem& i
         throw Error("GUI::Model::DomainObjectBuilder::buildParticleLayout()"
                     " -> Error! Not implemented");
     }
-    InterferenceItem* interference = item.interference();
+    InterferenceItem* interference = item.interference().currentItem();
     if (interference) {
         auto P_interference = buildInterference(*interference);
         if (P_interference)
diff --git a/GUI/Models/ParticleLayoutItem.cpp b/GUI/Models/ParticleLayoutItem.cpp
index 68074cffdf2..b1babb1589c 100644
--- a/GUI/Models/ParticleLayoutItem.cpp
+++ b/GUI/Models/ParticleLayoutItem.cpp
@@ -15,6 +15,7 @@
 #include "GUI/Models/ParticleLayoutItem.h"
 #include "GUI/Models/DoubleDescriptor.h"
 #include "GUI/Models/InterferenceItems.h"
+#include "GUI/Models/ItemCatalog.h"
 #include "GUI/Models/Lattice2DItems.h"
 #include "GUI/Models/MesoCrystalItem.h"
 #include "GUI/Models/ParticleCompositionItem.h"
@@ -105,9 +106,47 @@ void ParticleLayoutItem::removeParticle(ItemWithParticles* particle)
     model()->removeItem(particle);
 }
 
-InterferenceItem* ParticleLayoutItem::interference() const
+SelectionDescriptor<InterferenceItem*> ParticleLayoutItem::interference() const
 {
-    return dynamic_cast<InterferenceItem*>(getItem(T_INTERFERENCE));
+    SelectionDescriptor<InterferenceItem*> d;
+
+    // we need a special filling for this selection descriptor (not just from a GroupItem), since
+    // the interference is stored in a child, which can be present or not.
+
+    static QVector<QPair<QString, QString>> map;
+
+    // initialize if not done so far
+    if (map.isEmpty()) {
+        map << qMakePair(QString("None"), QString(""));
+        for (auto modelType : ItemCatalog::interferenceFunctionTypes())
+            map << qMakePair(ItemCatalog::instance().uiInfo(modelType).menuEntry, modelType);
+    }
+
+    d.label = "Interference function";
+
+    for (auto [title, type] : map)
+        d.options << title;
+
+    d.currentItem = [=] { return dynamic_cast<InterferenceItem*>(getItem(T_INTERFERENCE)); };
+
+    d.setCurrentIndex = [=](int current) {
+        if (auto item = getItem(T_INTERFERENCE))
+            model()->removeItem(item);
+        if (current > 0)
+            model()->insertNewItem(map[current].second, const_cast<ParticleLayoutItem*>(this), -1,
+                                   T_INTERFERENCE);
+    };
+
+    d.currentIndex = [=]() {
+        if (auto item = dynamic_cast<InterferenceItem*>(getItem(T_INTERFERENCE)))
+            for (int i = 1; i < map.size(); i++)
+                if (map[i].second == item->modelType())
+                    return i;
+
+        return 0;
+    };
+
+    return d;
 }
 
 void ParticleLayoutItem::setInterference(InterferenceItem* interference)
diff --git a/GUI/Models/ParticleLayoutItem.h b/GUI/Models/ParticleLayoutItem.h
index ebf7a5283e7..4fe59255891 100644
--- a/GUI/Models/ParticleLayoutItem.h
+++ b/GUI/Models/ParticleLayoutItem.h
@@ -15,6 +15,7 @@
 #ifndef BORNAGAIN_GUI_MODELS_PARTICLELAYOUTITEM_H
 #define BORNAGAIN_GUI_MODELS_PARTICLELAYOUTITEM_H
 
+#include "GUI/Models/SelectionDescriptor.h"
 #include "GUI/Models/SessionGraphicsItem.h"
 #include "GUI/Models/SessionModel.h"
 
@@ -41,7 +42,7 @@ public:
     void addParticle(ItemWithParticles* particle);
     void removeParticle(ItemWithParticles* particle);
 
-    InterferenceItem* interference() const;
+    SelectionDescriptor<InterferenceItem*> interference() const;
     template <typename T> T* createInterference();
     void setInterference(InterferenceItem* interference);
 
diff --git a/GUI/Views/RealSpaceWidgets/RealSpaceBuilder.cpp b/GUI/Views/RealSpaceWidgets/RealSpaceBuilder.cpp
index a3bc2f96717..9058d03b8a3 100644
--- a/GUI/Views/RealSpaceWidgets/RealSpaceBuilder.cpp
+++ b/GUI/Views/RealSpaceWidgets/RealSpaceBuilder.cpp
@@ -36,7 +36,7 @@ namespace {
 
 std::unique_ptr<IInterference> GetInterference(const ParticleLayoutItem& layoutItem)
 {
-    auto interferenceItem = layoutItem.interference();
+    auto interferenceItem = layoutItem.interference().currentItem();
     if (interferenceItem) {
         auto P_interference = interferenceItem->createInterference();
         if (P_interference)
-- 
GitLab