diff --git a/GUI/Model/Descriptor/SelectionDescriptor.h b/GUI/Model/Descriptor/SelectionDescriptor.h deleted file mode 100644 index 697ea680ed7ff31bbc582675473fed42d872765f..0000000000000000000000000000000000000000 --- a/GUI/Model/Descriptor/SelectionDescriptor.h +++ /dev/null @@ -1,76 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/Model/Descriptor/SelectionDescriptor.h -//! @brief Defines class SelectionDescriptor -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2021 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONDESCRIPTOR_H -#define BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONDESCRIPTOR_H - -#include "GUI/Util/ComboProperty.h" -#include <QString> -#include <QStringList> -#include <functional> - -//! Abstract base class for SelectionDescriptor to ease referencing. -class AbstractSelectionDescriptor { -public: - virtual ~AbstractSelectionDescriptor() = default; - - //! Set currently selected option - virtual void setCurrentIndex(int newIndex) const = 0; - - //! Get currently selected option - virtual int currentIndex() const = 0; -}; - -//! Describes a selection (various possibilities and the current one). -//! -//! Usually a selection is presented as a combo box. -//! -//! SelectionDescriptor operate on a SelectionProperty. Please refer to this class for more -//! information. -//! -//! The template parameter defines the type of the current item. This can be a pointer to a common -//! base class (like RotationItem*), but it also can be a std::variant<...>, which is useful if -//! no dedicated common base class exists (like for the roughness items LayerZeroRoughnessItem and -//! LayerBasicRoughnessItem). -//! If used with a ComboProperty holder, the template parameter can be a QString, so currentItem() -//! returns the currently selected string. -//! -//! Note that this class does not provide (*implement*) a selection, but *provide -//! information* about a selection. For implementing a selection, please see SelectionProperty. -//! -//! For easy UI creation, there are functions like GUI:Util::createSelectionCombo() which take a -//! descriptor and fully initialize the created combo box. -//! -//! \sa SelectionProperty -//! -template <typename T> -class SelectionDescriptor : public AbstractSelectionDescriptor { -public: - SelectionDescriptor() = default; - - operator T() const { return currentItem(); } - - void setCurrentIndex(int newIndex) const override { currentIndexSetter(newIndex); } - - int currentIndex() const override { return currentIndexGetter(); } - - QString label; //!< A label text (short, no trailing colon) - QString tooltip; //!< Tooltip text - QStringList options; //!< List of options, usually presented as combo entries - std::function<void(int)> currentIndexSetter; //!< Function to set currently selected option - std::function<int()> currentIndexGetter; //!< Function to get currently selected option - std::function<T()> currentItem; //!< Function to get currently selected item -}; - -#endif // BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONDESCRIPTOR_H diff --git a/GUI/Model/Descriptor/SelectionProperty.h b/GUI/Model/Descriptor/SelectionProperty.h index e35dd80d43bb5d39d175a70a110bfb06bf3aa36b..3af069b987bf409bb0fccfd4638553bb6335163f 100644 --- a/GUI/Model/Descriptor/SelectionProperty.h +++ b/GUI/Model/Descriptor/SelectionProperty.h @@ -15,9 +15,20 @@ #ifndef BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONPROPERTY_H #define BORNAGAIN_GUI_MODEL_DESCRIPTOR_SELECTIONPROPERTY_H -#include "GUI/Model/Descriptor/SelectionDescriptor.h" #include "GUI/Support/XML/Streamer.h" +//! Abstract base class for SelectionProperty to ease referencing. +class AbstractSelectionProperty { +public: + virtual ~AbstractSelectionProperty() = default; + + //! Set currently selected option + virtual void setCurrentIndex(int newIndex) = 0; + + //! Get currently selected option + virtual int currentIndex() const = 0; +}; + //! Class for representing a selection, its attributes and its accessors. //! //! A "selection" in this context is a class instance out of a range of possible class instances. @@ -34,22 +45,13 @@ //! pointer is handled in here. //! * label: a label of e.g. a spin box //! * tooltip: tooltip for e.g. a spin box -//! * persistent tag: a name to serialize this property. Do not change this string, since it is -//! serialized! -//! * A list of available options (e.g. the names of the distributions) -//! * A descriptor which provides some of the given information, as well as getters/setters. +//! * a list of available options (e.g. the names of the distributions) +//! * setters and getters //! -//! For the initialization of a SelectionProperty there are helper methods. They are not necessarily -//! to be called if they are not convenient. They are only there to help initialization e.g by using -//! a catalog. If no catalog exists for the given case, the initialization can be done by any means. -//! -//! This means especially that this class is **not** relying on the existence of a related catalog -//! class - a catalog helps but is not mandatory. -//! -//! \sa SelectionDescriptor +//! The initialization of a SelectionProperty is done using a catalog. //! template <typename Catalog> -class SelectionProperty { +class SelectionProperty : public AbstractSelectionProperty { public: using CatalogedType = typename Catalog::CatalogedType; @@ -61,8 +63,8 @@ public: template <typename... ArgsForCreation> void init(const QString& label, const QString& tooltip, ArgsForCreation... argsForCreation) { - initDescriptor(label, tooltip, argsForCreation...); - m_descriptor.setCurrentIndex(0); + initFieldsAndSetter(label, tooltip, argsForCreation...); + setCurrentIndex(0); } //! Initialize by means of a catalog class and an initializer function. @@ -82,8 +84,8 @@ public: { m_initializer = initializer; - initDescriptor(label, tooltip); - m_descriptor.setCurrentIndex(0); + initFieldsAndSetter(label, tooltip); + setCurrentIndex(0); } //! Initialize by means of a catalog class, a subsection of allowed types and an initializer @@ -106,21 +108,18 @@ public: m_initializer = initializer; m_types = types; - initDescriptor(label, tooltip); - m_descriptor.setCurrentIndex(0); + initFieldsAndSetter(label, tooltip); + setCurrentIndex(0); } - //! Cast to a descriptor working on this property. - operator SelectionDescriptor<CatalogedType*>() const { return m_descriptor; } - //! Direct access to the stored pointer CatalogedType* operator->() const { return m_p.get(); } //! Direct access to the stored pointer - CatalogedType* get() const { return m_p.get(); } + CatalogedType* currentItem() const { return m_p.get(); } //! Directly set the new item. - void set(CatalogedType* t, bool callInitializer = false) + void setCurrentItem(CatalogedType* t, bool callInitializer = false) { if (callInitializer && m_initializer) m_initializer(t, m_p.get()); @@ -129,7 +128,7 @@ public: //! Directly set the new item. template <typename S, typename... ArgsForConstructor> - S* set(ArgsForConstructor... argsForConstructor) + S* setCurrentItem(ArgsForConstructor... argsForConstructor) { S* s = new S(argsForConstructor...); if (s != nullptr && m_initializer) @@ -141,47 +140,52 @@ public: template <typename... ArgsForCreation> void rwSelected(Streamer& s, const QString& tag, ArgsForCreation... argsForCreation) { - if (QXmlStreamWriter* w = s.xmlWriter()) { + if (s.xmlWriter()) { s.write<Catalog>(tag, m_p.get()); - } else if (QXmlStreamReader* r = s.xmlReader()) { + } else if (s.xmlReader()) { CatalogedType* p = nullptr; s.read<Catalog>(tag, p, argsForCreation...); m_p.reset(p); } } + QString label() const { return m_label; } + QString tooltip() const { return m_tooltip; } + QStringList options() const { return m_options; } + + void setCurrentIndex(int newIndex) override { currentIndexSetter(newIndex); } + int currentIndex() const override { return m_types.indexOf(Catalog::type(m_p.get())); } + private: template <typename... ArgsForCreation> - void initDescriptor(const QString& label, const QString& tooltip, - ArgsForCreation... argsForCreation) - + void initFieldsAndSetter(const QString& label, const QString& tooltip, + ArgsForCreation... argsForCreation) { - auto setCurrentIndex = [=](int current) { + m_label = label; + m_tooltip = tooltip; + m_options.clear(); + for (const auto type : m_types) + m_options << Catalog::uiInfo(type).menuEntry; + + currentIndexSetter = [=](int current) { auto* p = Catalog::create(m_types[current], argsForCreation...); if (m_initializer) m_initializer(p, m_p.get()); m_p.reset(p); }; - - m_descriptor.label = label; - m_descriptor.tooltip = tooltip; - for (const auto type : m_types) - m_descriptor.options << Catalog::uiInfo(type).menuEntry; - m_descriptor.currentIndexSetter = setCurrentIndex; - m_descriptor.currentIndexGetter = [=]() { - return m_types.indexOf(Catalog::type(m_p.get())); - }; - m_descriptor.currentItem = [=] { return m_p.get(); }; } private: - SelectionDescriptor<CatalogedType*> - m_descriptor; //!< descriptor, holding attributes like label, tooltip - std::unique_ptr<CatalogedType> m_p; //!< Current selection + QString m_label; //!< A label text (short, no trailing colon) + QString m_tooltip; //!< Tooltip text + QStringList m_options; //!< List of options, usually presented as combo entries QVector<typename Catalog::Type> m_types = Catalog::types(); + //! Reimplementable function to set currently selected option. + std::function<void(int)> currentIndexSetter = nullptr; + //! initializer function. Can be empty. //! The first argument is the new item, the second is the old one if present; can be null. //! This is intended to maybe copy values from the old to the new selection. oldItem also can be diff --git a/GUI/Model/Device/BeamDistributionItem.cpp b/GUI/Model/Device/BeamDistributionItem.cpp index 61bc6342e68c084ea72bdfa6fdeb2aabcac7f7c0..71c6c8c8630813258ddce037d6bd8db73dec4cf3 100644 --- a/GUI/Model/Device/BeamDistributionItem.cpp +++ b/GUI/Model/Device/BeamDistributionItem.cpp @@ -19,7 +19,7 @@ std::unique_ptr<ParameterDistribution> BeamDistributionItem::getParameterDistributionForName( ParameterDistribution::WhichParameter which) const { - if (const auto* d = distribution()) { + if (const auto* d = distributionItem()) { auto distribution1D = createDistribution1D(); if (distribution1D) { @@ -39,14 +39,14 @@ double BeamDistributionItem::meanValue() const std::unique_ptr<IDistribution1D> domainDistr = createDistribution1D(); if (domainDistr) return domainDistr->mean() / scaleFactor(); - return dynamic_cast<SymmetricResolutionItem*>(distribution())->mean(); + return dynamic_cast<SymmetricResolutionItem*>(distributionItem())->mean(); } void BeamDistributionItem::resetToValue(double value) { auto* d = new DistributionNoneItem(); d->setMean(value); - m_distribution.set(d); + m_distribution.setCurrentItem(d); } double BeamDistributionItem::scaleFactor() const @@ -54,22 +54,7 @@ double BeamDistributionItem::scaleFactor() const return 1.0; } -DistributionItem* BeamDistributionItem::distribution() const -{ - return m_distribution.get(); -} - -SelectionDescriptor<DistributionItem*> BeamDistributionItem::distributionSelection() const -{ - return m_distribution; -} - -void BeamDistributionItem::setDistribution(DistributionItem* d) -{ - m_distribution.set(d); -} - std::unique_ptr<IDistribution1D> BeamDistributionItem::createDistribution1D() const { - return distribution()->createDistribution(scaleFactor()); + return distributionItem()->createDistribution(scaleFactor()); } diff --git a/GUI/Model/Device/BeamDistributionItem.h b/GUI/Model/Device/BeamDistributionItem.h index ccba2f001390ca2b4bad5e6fbdb49a53bb819131..f1247995ccadf904ffea9ca4625ee11b2e1d1f3c 100644 --- a/GUI/Model/Device/BeamDistributionItem.h +++ b/GUI/Model/Device/BeamDistributionItem.h @@ -39,9 +39,8 @@ public: template <typename T> T* setDistributionType(); - DistributionItem* distribution() const; - SelectionDescriptor<DistributionItem*> distributionSelection() const; - void setDistribution(DistributionItem* d); + DistributionItem* distributionItem() const { return m_distribution.currentItem(); } + SelectionProperty<DistributionItemCatalog>& distribution() { return m_distribution; } protected: virtual std::unique_ptr<IDistribution1D> createDistribution1D() const; @@ -52,8 +51,8 @@ protected: template <typename T> T* BeamDistributionItem::setDistributionType() { - m_distribution.set<T>(); - return dynamic_cast<T*>(m_distribution.get()); + m_distribution.setCurrentItem<T>(); + return dynamic_cast<T*>(m_distribution.currentItem()); } #endif // BORNAGAIN_GUI_MODEL_DEVICE_BEAMDISTRIBUTIONITEM_H diff --git a/GUI/Model/Device/BeamItems.cpp b/GUI/Model/Device/BeamItems.cpp index 5071c4df50f6a90101af31f662711558ce54ce6d..3d2593853cfc8de0a8ce732bbc740651768fa35d 100644 --- a/GUI/Model/Device/BeamItems.cpp +++ b/GUI/Model/Device/BeamItems.cpp @@ -168,24 +168,14 @@ BasicAxisItem* SpecularBeamItem::inclinationAxis() const return inclinationAngleItem()->alphaAxis(); } -FootprintItem* SpecularBeamItem::footprint() const -{ - return m_footprint.get(); -} - -SelectionDescriptor<FootprintItem*> SpecularBeamItem::footprintSelection() const -{ - return m_footprint; -} - void SpecularBeamItem::setGaussianFootprint(double value) { - m_footprint.set(new FootprintGaussianItem(value)); + m_footprint.setCurrentItem(new FootprintGaussianItem(value)); } void SpecularBeamItem::setSquareFootprint(double value) { - m_footprint.set(new FootprintSquareItem(value)); + m_footprint.setCurrentItem(new FootprintSquareItem(value)); } void SpecularBeamItem::updateToData(const IAxis& axis, QString units) diff --git a/GUI/Model/Device/BeamItems.h b/GUI/Model/Device/BeamItems.h index d781482fd0b5a95a562f34915c89d8f779d9da01..8e893fa249d101114eddd08543087e72b951938e 100644 --- a/GUI/Model/Device/BeamItems.h +++ b/GUI/Model/Device/BeamItems.h @@ -16,7 +16,6 @@ #define BORNAGAIN_GUI_MODEL_DEVICE_BEAMITEMS_H #include "GUI/Model/CatDevice/FootprintItemCatalog.h" -#include "GUI/Model/Descriptor/SelectionDescriptor.h" #include "GUI/Model/Descriptor/SelectionProperty.h" #include "GUI/Model/Device/BeamAngleItems.h" #include "GUI/Model/Device/BeamWavelengthItem.h" @@ -80,12 +79,10 @@ public: SpecularBeamInclinationItem* inclinationAngleItem() const override; BasicAxisItem* inclinationAxis() const; - FootprintItem* footprint() const; - SelectionDescriptor<FootprintItem*> footprintSelection() const; + SelectionProperty<FootprintItemCatalog>& footprint() { return m_footprint; } + void setGaussianFootprint(double value); void setSquareFootprint(double value); - template <typename T> - T* setFootprintType(); void updateToData(const IAxis& axis, QString units); void updateWavelength(); diff --git a/GUI/Model/Device/BeamWavelengthItem.cpp b/GUI/Model/Device/BeamWavelengthItem.cpp index 358b8e0769820cd302f27a72a088f8fa749a30a1..db7f8371752dc4ee4336cd710204aaf865db29e0 100644 --- a/GUI/Model/Device/BeamWavelengthItem.cpp +++ b/GUI/Model/Device/BeamWavelengthItem.cpp @@ -85,7 +85,7 @@ SpecularBeamWavelengthItem::SpecularBeamWavelengthItem() void SpecularBeamWavelengthItem::setToRange(const RealLimits& limits) { - if (auto* symmetricDistribution = dynamic_cast<SymmetricResolutionItem*>(distribution())) { + if (auto* symmetricDistribution = dynamic_cast<SymmetricResolutionItem*>(distributionItem())) { if (!limits.isInRange(wavelength())) { const double new_value = limits.isLimited() ? (limits.upperLimit() - limits.lowerLimit()) / 2. : default_wl; diff --git a/GUI/Model/Device/DetectorItems.cpp b/GUI/Model/Device/DetectorItems.cpp index da7f88f39ed3dd7ab6bbaa550fc8868d7c99d60b..2180cfa06ef83a0fa70abc8048cf3f84892e5088 100644 --- a/GUI/Model/Device/DetectorItems.cpp +++ b/GUI/Model/Device/DetectorItems.cpp @@ -43,12 +43,7 @@ MaskItems& DetectorItem::maskItems() return m_maskItems; } -ResolutionFunctionItem* DetectorItem::resolutionFunction() const -{ - return m_resolutionFunction.get(); -} - -SelectionDescriptor<ResolutionFunctionItem*> DetectorItem::resolutionFunctionSelection() const +SelectionProperty<ResolutionFunctionItemCatalog>& DetectorItem::resolutionFunction() { return m_resolutionFunction; } diff --git a/GUI/Model/Device/DetectorItems.h b/GUI/Model/Device/DetectorItems.h index 7bcef7153858b8d033b49366eb4fd4345d1d9ea3..704f9ba4aba9e4799627ba2eddd26158ec87cb7b 100644 --- a/GUI/Model/Device/DetectorItems.h +++ b/GUI/Model/Device/DetectorItems.h @@ -49,8 +49,8 @@ public: void importMasks(const MaskContainerItem* maskContainer); MaskItems& maskItems(); - ResolutionFunctionItem* resolutionFunction() const; - SelectionDescriptor<ResolutionFunctionItem*> resolutionFunctionSelection() const; + SelectionProperty<ResolutionFunctionItemCatalog>& resolutionFunction(); + template <typename T> T* setResolutionFunctionType(); @@ -73,8 +73,8 @@ protected: template <typename T> T* DetectorItem::setResolutionFunctionType() { - m_resolutionFunction.set<T>(); - return dynamic_cast<T*>(m_resolutionFunction.get()); + m_resolutionFunction.setCurrentItem<T>(); + return dynamic_cast<T*>(m_resolutionFunction.currentItem()); } #endif // BORNAGAIN_GUI_MODEL_DEVICE_DETECTORITEMS_H diff --git a/GUI/Model/Device/InstrumentItems.cpp b/GUI/Model/Device/InstrumentItems.cpp index a8f4dd773f4807ec46fab38428b9ba752891e3be..607be6c9202a4476ff3d8d8381c06ed00af73072 100644 --- a/GUI/Model/Device/InstrumentItems.cpp +++ b/GUI/Model/Device/InstrumentItems.cpp @@ -85,7 +85,7 @@ InstrumentItem::InstrumentItem() "polarization"); m_analyzerDirection.init("Analyzer direction", "Direction of the polarization analysis", Unit::unitless, "analyzerDirection"); - m_backgroundItem.init("Background", ""); + m_background.init("Background", ""); } InstrumentItem* InstrumentItem::createCopy() const @@ -96,51 +96,11 @@ InstrumentItem* InstrumentItem::createCopy() const return copy; } -QString InstrumentItem::id() const -{ - return m_id; -} - -void InstrumentItem::setId(const QString& id) -{ - m_id = id; -} - -void InstrumentItem::setInstrumentName(const QString& instrumentName) -{ - m_name = instrumentName; -} - -QString InstrumentItem::instrumentName() const -{ - return m_name; -} - -QString InstrumentItem::description() const -{ - return m_description; -} - -void InstrumentItem::setDescription(const QString& description) -{ - m_description = description; -} - BeamItem* InstrumentItem::beamItem() const { return m_beamItem.get(); } -BackgroundItem* InstrumentItem::backgroundItem() const -{ - return m_backgroundItem.get(); -} - -SelectionDescriptor<BackgroundItem*> InstrumentItem::backgroundSelection() const -{ - return m_backgroundItem; -} - bool InstrumentItem::alignedWith(const RealItem* item) const { return shape() == item->shape(); @@ -173,7 +133,7 @@ void InstrumentItem::serialize(Streamer& s) m_analyzerDirection.rwProperty(s, Tag::AnalyzerDirection); Serialize::rwProperty(s, Tag::AnalyzerEfficiency, m_analyzerEfficiency); Serialize::rwProperty(s, Tag::AnalyzerTotalTransmission, m_analyzerTotalTransmission); - m_backgroundItem.rwSelected(s, Tag::Background); + m_background.rwSelected(s, Tag::Background); Serialize::rwClass(s, Tag::Beam, *m_beamItem); } @@ -352,24 +312,14 @@ const ICoordSystem* DepthProbeInstrumentItem::createCoordSystem() const Instrument2DItem::Instrument2DItem() { m_beamItem.reset(new GISASBeamItem()); - m_detectorItem.init("Detector", ""); + m_detector.init("Detector", ""); } void Instrument2DItem::serialize(Streamer& s) { s.assertVersion(0); Serialize::rwBaseClass<InstrumentItem>(s, "InstrumentItem", this); - m_detectorItem.rwSelected(s, Tag::Detector); -} - -DetectorItem* Instrument2DItem::detectorItem() const -{ - return m_detectorItem.get(); -} - -SelectionDescriptor<DetectorItem*> Instrument2DItem::detectorSelection() const -{ - return m_detectorItem; + m_detector.rwSelected(s, Tag::Detector); } void Instrument2DItem::importMasks(const MaskContainerItem* maskContainer) diff --git a/GUI/Model/Device/InstrumentItems.h b/GUI/Model/Device/InstrumentItems.h index 9a5b13ebb8afb033c1d5944e18cd510bff2f19ba..ba919d309ac885293e68d32dca91bbed5f3d3c94 100644 --- a/GUI/Model/Device/InstrumentItems.h +++ b/GUI/Model/Device/InstrumentItems.h @@ -18,7 +18,6 @@ #include "GUI/Model/CatDevice/BackgroundItemCatalog.h" #include "GUI/Model/CatDevice/DetectorItemCatalog.h" #include "GUI/Model/Descriptor/AxisProperty.h" -#include "GUI/Model/Descriptor/SelectionDescriptor.h" #include "GUI/Model/Descriptor/SelectionProperty.h" #include "GUI/Model/Descriptor/VectorProperty.h" #include "GUI/Model/Device/BackgroundItems.h" @@ -50,11 +49,11 @@ public: virtual void serialize(Streamer& s); - QString id() const; - void setId(const QString& id); + QString id() const { return m_id; } + void setId(const QString& id) { m_id = id; } - void setInstrumentName(const QString& instrumentName); - QString instrumentName() const; + QString instrumentName() const { return m_name; } + void setInstrumentName(const QString& instrumentName) { m_name = instrumentName; } //! The type as how to show it on the UI. Do not use for type checking or similar! virtual QString instrumentType() const = 0; @@ -65,15 +64,15 @@ public: return dynamic_cast<const T*>(this) != nullptr; } - QString description() const; - void setDescription(const QString& description); + QString description() const { return m_description; } + void setDescription(const QString& description) { m_description = description; } virtual BeamItem* beamItem() const; - BackgroundItem* backgroundItem() const; template <typename T> T* setBackgroundType(); - SelectionDescriptor<BackgroundItem*> backgroundSelection() const; + SelectionProperty<BackgroundItemCatalog>& background() { return m_background; } + BackgroundItem* backgroundItem() const { return m_background.currentItem(); } virtual std::vector<int> shape() const = 0; @@ -116,7 +115,7 @@ protected: QString m_name; QString m_description; bool m_withPolarizerAnalyzer; - SelectionProperty<BackgroundItemCatalog> m_backgroundItem; + SelectionProperty<BackgroundItemCatalog> m_background; std::unique_ptr<BeamItem> m_beamItem; VectorProperty m_polarization; @@ -174,10 +173,10 @@ class Instrument2DItem : public InstrumentItem { public: void serialize(Streamer& s) override; - DetectorItem* detectorItem() const; template <typename T> T* setDetectorType(); - SelectionDescriptor<DetectorItem*> detectorSelection() const; + DetectorItem* detectorItem() const { return m_detector.currentItem(); } + SelectionProperty<DetectorItemCatalog>& detector() { return m_detector; } void importMasks(const MaskContainerItem* maskContainer) override; @@ -190,7 +189,7 @@ public: protected: Instrument2DItem(); - SelectionProperty<DetectorItemCatalog> m_detectorItem; + SelectionProperty<DetectorItemCatalog> m_detector; }; @@ -232,15 +231,15 @@ protected: template <typename T> T* InstrumentItem::setBackgroundType() { - m_backgroundItem.set<T>(); - return dynamic_cast<T*>(m_backgroundItem.get()); + m_background.setCurrentItem<T>(); + return dynamic_cast<T*>(m_background.currentItem()); } template <typename T> T* Instrument2DItem::setDetectorType() { - m_detectorItem.set<T>(); - return dynamic_cast<T*>(m_detectorItem.get()); + m_detector.setCurrentItem<T>(); + return dynamic_cast<T*>(m_detector.currentItem()); } #endif // BORNAGAIN_GUI_MODEL_DEVICE_INSTRUMENTITEMS_H diff --git a/GUI/Model/Device/RectangularDetectorItem.h b/GUI/Model/Device/RectangularDetectorItem.h index 71a1a4ace12e4cd4eed68f3e0e9e4c61f26be599..9e271576ce69909e5d17171861a1606e7da667ae 100644 --- a/GUI/Model/Device/RectangularDetectorItem.h +++ b/GUI/Model/Device/RectangularDetectorItem.h @@ -18,6 +18,7 @@ #include "Device/Detector/RectangularDetector.h" #include "GUI/Model/Descriptor/VectorProperty.h" #include "GUI/Model/Device/DetectorItems.h" +#include "GUI/Util/ComboProperty.h" class RectangularDetectorItem : public DetectorItem { public: diff --git a/GUI/Model/FromCore/ItemizeSample.cpp b/GUI/Model/FromCore/ItemizeSample.cpp index 6e7d1c79dbff2700e47f21c2a6975cabffe33952..7e9ecb11dfe6cd65583e1eb3a2d0b9ecb83c4c04 100644 --- a/GUI/Model/FromCore/ItemizeSample.cpp +++ b/GUI/Model/FromCore/ItemizeSample.cpp @@ -134,20 +134,20 @@ void setDecayFunction1D(Interference1DLatticeItem* parent, const IProfile1D* ipd if (const auto* pdf = dynamic_cast<const Profile1DCauchy*>(ipdf)) { auto* item = new Profile1DCauchyItem(); item->setOmega(pdf->omega()); - parent->setDecayFunction(item); + parent->setDecayFunctionType(item); } else if (const auto* pdf = dynamic_cast<const Profile1DGauss*>(ipdf)) { auto* item = new Profile1DGaussItem(); item->setOmega(pdf->omega()); - parent->setDecayFunction(item); + parent->setDecayFunctionType(item); } else if (const auto* pdf = dynamic_cast<const Profile1DTriangle*>(ipdf)) { auto* item = new Profile1DTriangleItem(); item->setOmega(pdf->omega()); - parent->setDecayFunction(item); + parent->setDecayFunctionType(item); } else if (const auto* pdf = dynamic_cast<const Profile1DVoigt*>(ipdf)) { auto* item = new Profile1DVoigtItem(); item->setOmega(pdf->omega()); item->setEta(pdf->eta()); - parent->setDecayFunction(item); + parent->setDecayFunctionType(item); } else throw Error("GUI::Transform::FromCore::setDecayFunction1D: -> Error"); } @@ -324,25 +324,25 @@ void setLayerItem(LayerItem* parent, const Layer* layer, const LayerInterface* t void setRotation(ItemWithParticles* parent, const IRotation* rotation) { if (!rotation) - parent->setRotation(nullptr); + parent->setRotationType(nullptr); else if (const auto* r = dynamic_cast<const RotationX*>(rotation)) { auto* item = new XRotationItem(); item->setAngle(Units::rad2deg(r->angle())); - parent->setRotation(item); + parent->setRotationType(item); } else if (const auto* r = dynamic_cast<const RotationY*>(rotation)) { auto* item = new YRotationItem(); item->setAngle(Units::rad2deg(r->angle())); - parent->setRotation(item); + parent->setRotationType(item); } else if (const auto* r = dynamic_cast<const RotationZ*>(rotation)) { auto* item = new ZRotationItem(); item->setAngle(Units::rad2deg(r->angle())); - parent->setRotation(item); + parent->setRotationType(item); } else if (const auto* r = dynamic_cast<const RotationEuler*>(rotation)) { auto* item = new EulerRotationItem(); item->setAlpha(Units::rad2deg(r->alpha())); item->setBeta(Units::rad2deg(r->beta())); item->setGamma(Units::rad2deg(r->gamma())); - parent->setRotation(item); + parent->setRotationType(item); } } diff --git a/GUI/Model/Model/ParameterTreeUtils.cpp b/GUI/Model/Model/ParameterTreeUtils.cpp index 61a31398867ebab551e282007cb01fc72ed69786..ca2c0dae05b00a12a13484f06b2d2bc68640be92 100644 --- a/GUI/Model/Model/ParameterTreeUtils.cpp +++ b/GUI/Model/Model/ParameterTreeUtils.cpp @@ -254,7 +254,7 @@ ParameterLabelItem* ParameterTreeBuilder::addParticle(ParameterLabelItem* parent addRotation(label, p); if (const auto* particle = dynamic_cast<const ParticleItem*>(p)) { - auto* formFactor = particle->formfactor(); + auto* formFactor = particle->formfactorItem(); auto* ffLabel = addLabel<FormFactorItemCatalog>(label, "Formfactor", formFactor); for (auto& d : formFactor->geometryProperties()) addParameterItem(ffLabel, d); @@ -286,7 +286,7 @@ ParameterLabelItem* ParameterTreeBuilder::addParticle(ParameterLabelItem* parent void ParameterTreeBuilder::addLattice(ParameterLabelItem* parentLabel, const Interference2DAbstractLatticeItem* itf) { - auto* lattice = itf->latticeType().currentItem(); + auto* lattice = itf->latticeTypeItem(); auto* label = addLabel<Lattice2DItemCatalog>(parentLabel, "Lattice", lattice); for (auto& d : lattice->geometryValues(!itf->xiIntegration())) addParameterItem(label, d); @@ -350,7 +350,7 @@ void ParameterTreeBuilder::addBeamDistribution(ParameterLabelItem* parentLabel, BeamDistributionItem* distributionItem, const QString& label, bool withMean) { - auto* distribution = distributionItem->distribution(); + auto* distribution = distributionItem->distributionItem(); if (auto* dn = dynamic_cast<DistributionNoneItem*>(distribution)) { if (withMean) addParameterItem(parentLabel, dn->mean(), label); @@ -368,7 +368,7 @@ void ParameterTreeBuilder::addDetector(ParameterLabelItem* parentLabel, Detector { const auto addResolutionFunction = [=](ParameterLabelItem* detLabel) { if (auto* r = dynamic_cast<ResolutionFunction2DGaussianItem*>( - detector->resolutionFunctionSelection().currentItem())) { + detector->resolutionFunction().currentItem())) { auto* label = new ParameterLabelItem("Resolution (Gaussian)", detLabel); addParameterItem(label, r->sigmaX()); addParameterItem(label, r->sigmaY()); diff --git a/GUI/Model/Sample/InterferenceItems.cpp b/GUI/Model/Sample/InterferenceItems.cpp index 1dee93a69eeb18531157fef6c558887472a940e0..817b17edf50ad4d63acf6176dc4a00b74f5e1df2 100644 --- a/GUI/Model/Sample/InterferenceItems.cpp +++ b/GUI/Model/Sample/InterferenceItems.cpp @@ -88,7 +88,7 @@ Interference2DAbstractLatticeItem::Interference2DAbstractLatticeItem(bool xiInte : m_xiIntegration(xiIntegration) { m_latticeType.init("Lattice type", ""); - m_latticeType.set(new HexagonalLattice2DItem()); + m_latticeType.setCurrentItem(new HexagonalLattice2DItem()); } // --------------------------------------------------------------------------------------------- // @@ -101,7 +101,7 @@ Interference2DLatticeItem::Interference2DLatticeItem() std::unique_ptr<IInterference> Interference2DLatticeItem::createInterference() const { - Lattice2DItem* latticeItem = latticeType().currentItem(); + Lattice2DItem* latticeItem = latticeTypeItem(); std::unique_ptr<Interference2DLattice> result( new Interference2DLattice(*latticeItem->createLattice())); @@ -138,7 +138,7 @@ Interference2DParacrystalItem::Interference2DParacrystalItem() std::unique_ptr<IInterference> Interference2DParacrystalItem::createInterference() const { - Lattice2DItem* latticeItem = latticeType().currentItem(); + Lattice2DItem* latticeItem = latticeTypeItem(); std::unique_ptr<Interference2DParacrystal> result( new Interference2DParacrystal(*latticeItem->createLattice(), 0, 0, 0)); @@ -173,7 +173,7 @@ InterferenceFinite2DLatticeItem::InterferenceFinite2DLatticeItem() std::unique_ptr<IInterference> InterferenceFinite2DLatticeItem::createInterference() const { - Lattice2DItem* latticeItem = latticeType().currentItem(); + Lattice2DItem* latticeItem = latticeTypeItem(); auto result = std::make_unique<InterferenceFinite2DLattice>(*latticeItem->createLattice(), m_domainSize1, m_domainSize2); diff --git a/GUI/Model/Sample/InterferenceItems.h b/GUI/Model/Sample/InterferenceItems.h index ca9f8100f04dc066a928141843f28025941235bc..97cd2306ff521e2ef81e941f4b164e8726c1257e 100644 --- a/GUI/Model/Sample/InterferenceItems.h +++ b/GUI/Model/Sample/InterferenceItems.h @@ -59,8 +59,8 @@ public: const DoubleProperty& rotationAngle() const { return m_rotationAngle; } void setRotationAngle(double v) { m_rotationAngle.setValue(v); } - void setDecayFunction(Profile1DItem* p) { m_decayFunction.set(p); } - SelectionDescriptor<Profile1DItem*> decayFunction() const { return m_decayFunction; } + SelectionProperty<Profile1DItemCatalog>& decayFunction() { return m_decayFunction; } + void setDecayFunctionType(Profile1DItem* p) { m_decayFunction.setCurrentItem(p); } private: DoubleProperty m_length; @@ -72,11 +72,12 @@ private: class Interference2DAbstractLatticeItem : public InterferenceItem { public: - SelectionDescriptor<Lattice2DItem*> latticeType() const { return m_latticeType; } - void setLatticeType(Lattice2DItem* p) { m_latticeType.set(p); } + Lattice2DItem* latticeTypeItem() const { return m_latticeType.currentItem(); } + SelectionProperty<Lattice2DItemCatalog>& latticeType() { return m_latticeType; } + void setLatticeType(Lattice2DItem* p) { m_latticeType.setCurrentItem(p); } bool xiIntegration() const { return m_xiIntegration; } - void setXiIntegration(bool xiIntegration) { m_xiIntegration = xiIntegration; } + void setXiIntegration(bool b) { m_xiIntegration = b; } protected: explicit Interference2DAbstractLatticeItem(bool xiIntegration); @@ -93,8 +94,8 @@ public: std::unique_ptr<IInterference> createInterference() const override; void serialize(Streamer& s) override; - void setDecayFunctionType(Profile2DItem* p) { m_decayFunction.set(p); } - SelectionDescriptor<Profile2DItem*> decayFunction() const { return m_decayFunction; } + SelectionProperty<Profile2DItemCatalog>& decayFunction() { return m_decayFunction; } + void setDecayFunctionType(Profile2DItem* p) { m_decayFunction.setCurrentItem(p); } protected: SelectionProperty<Profile2DItemCatalog> m_decayFunction; @@ -120,11 +121,11 @@ public: const DoubleProperty& domainSize2() const { return m_domainSize2; } void setDomainSize2(double size) { m_domainSize2.setValue(size); } - SelectionDescriptor<Profile2DItem*> probabilityDistribution1() const { return m_pdf1; } - void setPDF1Type(Profile2DItem* p) { m_pdf1.set(p); } + SelectionProperty<Profile2DItemCatalog>& probabilityDistribution1() { return m_pdf1; } + void setPDF1Type(Profile2DItem* p) { m_pdf1.setCurrentItem(p); } - SelectionDescriptor<Profile2DItem*> probabilityDistribution2() const { return m_pdf2; } - void setPDF2Type(Profile2DItem* p) { m_pdf2.set(p); } + SelectionProperty<Profile2DItemCatalog>& probabilityDistribution2() { return m_pdf2; } + void setPDF2Type(Profile2DItem* p) { m_pdf2.setCurrentItem(p); } private: DoubleProperty m_dampingLength; @@ -198,8 +199,8 @@ public: const DoubleProperty& kappa() const { return m_kappa; } void setKappa(double v) { m_kappa.setValue(v); } - SelectionDescriptor<Profile1DItem*> probabilityDistribution() const { return m_pdf; } - void setPDFType(Profile1DItem* p) { m_pdf.set(p); } + SelectionProperty<Profile1DItemCatalog>& probabilityDistribution() { return m_pdf; } + void setPDFType(Profile1DItem* p) { m_pdf.setCurrentItem(p); } private: DoubleProperty m_peakDistance; diff --git a/GUI/Model/Sample/ItemWithParticles.cpp b/GUI/Model/Sample/ItemWithParticles.cpp index c6b5478f0d98500a094d54db710df49838057a9d..ef81e55f85f0a39f25b76a10537eb107889982b4 100644 --- a/GUI/Model/Sample/ItemWithParticles.cpp +++ b/GUI/Model/Sample/ItemWithParticles.cpp @@ -30,7 +30,7 @@ ItemWithParticles::ItemWithParticles(const QString& abundanceTooltip, std::unique_ptr<IRotation> ItemWithParticles::createRotation() const { - if (!m_rotation.get()) + if (!m_rotation.currentItem()) return {}; const auto matrix = m_rotation->rotation(); return std::unique_ptr<IRotation>(IRotation::createRotation(matrix)); diff --git a/GUI/Model/Sample/ItemWithParticles.h b/GUI/Model/Sample/ItemWithParticles.h index 9c13d727b985324e9c7a892f4208ebe5e3ebdb71..58070e652ccff96248a2ec25699ff8a0955805e5 100644 --- a/GUI/Model/Sample/ItemWithParticles.h +++ b/GUI/Model/Sample/ItemWithParticles.h @@ -37,11 +37,10 @@ public: const VectorProperty& position() const { return m_position; } void setPosition(const R3& position) { m_position.setR3(position); } - //! Returns selection descriptor for rotation methods. - SelectionDescriptor<RotationItem*> rotation() { return m_rotation; } + SelectionProperty<RotationItemCatalog>& rotation() { return m_rotation; } //! nullptr is allowed and sets to "no rotation" - void setRotation(RotationItem* p) { m_rotation.set(p); } + void setRotationType(RotationItem* p) { m_rotation.setCurrentItem(p); } //! nullptr only if "no rotation". Can contain identity! std::unique_ptr<IRotation> createRotation() const; diff --git a/GUI/Model/Sample/LayerItem.cpp b/GUI/Model/Sample/LayerItem.cpp index d04f9b498c6afc2d66e458be47f3c0ee78907171..1f0de3235599e2d73f36fad93f642911932ba0fa 100644 --- a/GUI/Model/Sample/LayerItem.cpp +++ b/GUI/Model/Sample/LayerItem.cpp @@ -92,19 +92,14 @@ QVector<ItemWithParticles*> LayerItem::itemsWithParticles() const return result; } -SelectionDescriptor<RoughnessItem*> LayerItem::roughness() -{ - return m_roughness; -} - void LayerItem::setBasicRoughness() { - m_roughness.set(new BasicRoughnessItem); + m_roughness.setCurrentItem(new BasicRoughnessItem); } void LayerItem::clearRoughness() { - m_roughness.set(nullptr); + m_roughness.setCurrentItem(nullptr); } QVector<ParticleLayoutItem*> LayerItem::layouts() const diff --git a/GUI/Model/Sample/LayerItem.h b/GUI/Model/Sample/LayerItem.h index c08481de9edbf250d06114593488e249d2a30e15..02cea0a10692c08d8c0292e4944ce8525d1b84e9 100644 --- a/GUI/Model/Sample/LayerItem.h +++ b/GUI/Model/Sample/LayerItem.h @@ -41,7 +41,7 @@ public: const DoubleProperty& thickness() const { return m_thickness; } void setThickness(double v) { m_thickness.setValue(v); } - SelectionDescriptor<RoughnessItem*> roughness(); + SelectionProperty<RoughnessItemCatalog>& roughness() { return m_roughness; } void setBasicRoughness(); void clearRoughness(); diff --git a/GUI/Model/Sample/MesocrystalItem.cpp b/GUI/Model/Sample/MesocrystalItem.cpp index ebac4d5e0b349d08e7b52a79544dd256b39dfd6c..b2fef110af0f7ea88fea2f9b2cc8e125c2bce822 100644 --- a/GUI/Model/Sample/MesocrystalItem.cpp +++ b/GUI/Model/Sample/MesocrystalItem.cpp @@ -109,16 +109,16 @@ Lattice3D MesocrystalItem::getLattice() const std::unique_ptr<IParticle> MesocrystalItem::getBasis() const { - if (auto* p = dynamic_cast<ParticleItem*>(m_basisParticle.get())) + if (auto* p = dynamic_cast<ParticleItem*>(m_basisParticle.currentItem())) return p->createParticle(); - if (auto* p = dynamic_cast<CoreAndShellItem*>(m_basisParticle.get())) + if (auto* p = dynamic_cast<CoreAndShellItem*>(m_basisParticle.currentItem())) return p->createCoreAndShell(); - if (auto* p = dynamic_cast<CompoundItem*>(m_basisParticle.get())) + if (auto* p = dynamic_cast<CompoundItem*>(m_basisParticle.currentItem())) return p->createCompound(); - if (auto* p = dynamic_cast<MesocrystalItem*>(m_basisParticle.get())) + if (auto* p = dynamic_cast<MesocrystalItem*>(m_basisParticle.currentItem())) return p->createMesocrystal(); return {}; @@ -129,17 +129,6 @@ std::unique_ptr<IFormFactor> MesocrystalItem::getOuterShape() const return m_outerShape->createFormFactor(); } -ItemWithParticles* MesocrystalItem::basisParticle() const -{ - return m_basisParticle.get(); -} - -void MesocrystalItem::setBasis(ItemWithParticles* basis) -{ - m_basisParticle.set(basis); -} - - QVector<ItemWithParticles*> MesocrystalItem::containedItemsWithParticles() const { QVector<ItemWithParticles*> result; diff --git a/GUI/Model/Sample/MesocrystalItem.h b/GUI/Model/Sample/MesocrystalItem.h index 44cc2096e75deaed637bc885e620f731cf9cb95c..34e4b204a36909a272c4eb8e0ce7a38732d68b6d 100644 --- a/GUI/Model/Sample/MesocrystalItem.h +++ b/GUI/Model/Sample/MesocrystalItem.h @@ -43,11 +43,11 @@ public: template <typename T> T* setOuterShapeType(); - SelectionDescriptor<FormFactorItem*> outerShape() const { return m_outerShape; } - void setOuterShape(FormFactorItem* p) { m_outerShape.set(p); } + SelectionProperty<FormFactorItemCatalog>& outerShape() { return m_outerShape; } + void setOuterShape(FormFactorItem* p) { m_outerShape.setCurrentItem(p); } - ItemWithParticles* basisParticle() const; - void setBasis(ItemWithParticles* basis); + ItemWithParticles* basisParticle() const { return m_basisParticle.currentItem(); } + void setBasis(ItemWithParticles* basis) { m_basisParticle.setCurrentItem(basis); } VectorProperty& vectorA() { return m_vectorA; } const VectorProperty& vectorA() const { return m_vectorA; } diff --git a/GUI/Model/Sample/ParticleItem.cpp b/GUI/Model/Sample/ParticleItem.cpp index f515e3fceb7a6f34804473ad12c132b4fcde34cb..664425be92263e1ba19046766159d688a1048206 100644 --- a/GUI/Model/Sample/ParticleItem.cpp +++ b/GUI/Model/Sample/ParticleItem.cpp @@ -46,7 +46,7 @@ ParticleItem::ParticleItem(const MaterialItems* materials) , ItemWithParticles(abundance_tooltip, position_tooltip) { m_formFactor.init("Form Factor", ""); - m_formFactor.set(new CylinderItem()); + m_formFactor.setCurrentItem(new CylinderItem()); } void ParticleItem::serialize(Streamer& s) @@ -74,12 +74,12 @@ std::unique_ptr<Particle> ParticleItem::createParticle() const void ParticleItem::setFormFactor(FormFactorItem* p) { - m_formFactor.set(p); + m_formFactor.setCurrentItem(p); } -FormFactorItem* ParticleItem::formfactor() const +FormFactorItem* ParticleItem::formfactorItem() const { - return m_formFactor.get(); + return m_formFactor.currentItem(); } QVector<ItemWithParticles*> ParticleItem::containedItemsWithParticles() const diff --git a/GUI/Model/Sample/ParticleItem.h b/GUI/Model/Sample/ParticleItem.h index 91428e50f7c3c688e3eef91b69e9a0705790b167..e635ae73b6fed04661aec8025acc3b636e99a56c 100644 --- a/GUI/Model/Sample/ParticleItem.h +++ b/GUI/Model/Sample/ParticleItem.h @@ -34,7 +34,7 @@ public: template <typename T> T* setFormFactorType(); void setFormFactor(FormFactorItem* p); - FormFactorItem* formfactor() const; + FormFactorItem* formfactorItem() const; QVector<ItemWithParticles*> containedItemsWithParticles() const override; private: diff --git a/GUI/Model/Sample/ParticleLayoutItem.cpp b/GUI/Model/Sample/ParticleLayoutItem.cpp index cdb3124223d1e9e79501715db30effd8b19c86e0..3ba10c2b5ad1bbd39b3c256f53b49b07498486c9 100644 --- a/GUI/Model/Sample/ParticleLayoutItem.cpp +++ b/GUI/Model/Sample/ParticleLayoutItem.cpp @@ -48,11 +48,11 @@ double ParticleLayoutItem::totalDensityValue() const if (!totalDensityIsDefinedByInterference()) return m_ownDensity.value(); - ASSERT(m_interference.get()); + ASSERT(m_interference.currentItem()); if (const auto* interLatticeItem = - dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.get())) { - Lattice2DItem* latticeItem = interLatticeItem->latticeType().currentItem(); + dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.currentItem())) { + Lattice2DItem* latticeItem = interLatticeItem->latticeTypeItem(); try { const double area = latticeItem->unitCellArea(); return area == 0.0 ? 0.0 : 1.0 / area; @@ -62,7 +62,8 @@ double ParticleLayoutItem::totalDensityValue() const } } - if (const auto* hd = dynamic_cast<const InterferenceHardDiskItem*>(m_interference.get())) + if (const auto* hd = + dynamic_cast<const InterferenceHardDiskItem*>(m_interference.currentItem())) return hd->density(); ASSERT(false); @@ -92,25 +93,15 @@ QVector<ItemWithParticles*> ParticleLayoutItem::containedItemsWithParticles() co return result; } -SelectionDescriptor<InterferenceItem*> ParticleLayoutItem::interference() const +const SelectionProperty<InterferenceItemCatalog>& ParticleLayoutItem::interference() const { return m_interference; } -void ParticleLayoutItem::setInterference(InterferenceItem* interference) -{ - m_interference.set(interference); -} - -void ParticleLayoutItem::removeInterference() -{ - m_interference.set(nullptr); -} - bool ParticleLayoutItem::totalDensityIsDefinedByInterference() const { - return dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.get()) - || dynamic_cast<const InterferenceHardDiskItem*>(m_interference.get()); + return dynamic_cast<const Interference2DAbstractLatticeItem*>(m_interference.currentItem()) + || dynamic_cast<const InterferenceHardDiskItem*>(m_interference.currentItem()); } void ParticleLayoutItem::serialize(Streamer& s) diff --git a/GUI/Model/Sample/ParticleLayoutItem.h b/GUI/Model/Sample/ParticleLayoutItem.h index 6fffa7e58a489c3f416929b91f6b2aeceebf865b..4c3e6fd1b6a1ccdf93e517f6457ba1e3256082cc 100644 --- a/GUI/Model/Sample/ParticleLayoutItem.h +++ b/GUI/Model/Sample/ParticleLayoutItem.h @@ -59,9 +59,10 @@ public: //! \sa particles() QVector<ItemWithParticles*> containedItemsWithParticles() const; - SelectionDescriptor<InterferenceItem*> interference() const; - void setInterference(InterferenceItem* interference); - void removeInterference(); + SelectionProperty<InterferenceItemCatalog>& interference() { return m_interference; } + const SelectionProperty<InterferenceItemCatalog>& interference() const; + void setInterference(InterferenceItem* i) { m_interference.setCurrentItem(i); } + void removeInterference() { m_interference.setCurrentItem(nullptr); } //! Returns whether total density is defined by the currently selected interference. //! diff --git a/GUI/Model/ToCore/SimulationToCore.cpp b/GUI/Model/ToCore/SimulationToCore.cpp index 1ec1f0dbbfed63beb37e1eb8edffad2c53d703b4..330ecfb6ef0840f7793f99ae499dc975af9bfa46 100644 --- a/GUI/Model/ToCore/SimulationToCore.cpp +++ b/GUI/Model/ToCore/SimulationToCore.cpp @@ -76,7 +76,7 @@ std::unique_ptr<ScanResolution> createScanResolution(const BeamDistributionItem* if (!item) return nullptr; - const auto* distr_item = dynamic_cast<const SymmetricResolutionItem*>(item->distribution()); + const auto* distr_item = dynamic_cast<const SymmetricResolutionItem*>(item->distributionItem()); if (!distr_item) return nullptr; @@ -130,7 +130,7 @@ SpecularSimulation* createSpecularSimulation(std::unique_ptr<MultiLayer> sample, { auto* beam_item = item->beamItem(); auto* const axis_item = beam_item->inclinationAxis(); - auto* const footprint_item = beam_item->footprint(); + auto* const footprint_item = beam_item->footprint().currentItem(); AlphaScan scan(beam_item->wavelength(), *axis_item->createAxis(Units::deg)); scan.setFootprintFactor(footprint_item->createFootprint().get()); diff --git a/GUI/View/Common/DoubleLineEdit.h b/GUI/View/Common/DoubleLineEdit.h index d41b2fa07118d742d8b79237ed5d469492c11f0c..2b77ef94d36ac63f516db988650aa197fe3f59eb 100644 --- a/GUI/View/Common/DoubleLineEdit.h +++ b/GUI/View/Common/DoubleLineEdit.h @@ -38,7 +38,7 @@ public: signals: //! Emitted whenever the value changes. //! - //! newBaseValue is in the unit of the valueDescriptor. + //! newBaseValue is in the unit of the valueProperty. void baseValueChanged(double newBaseValue); private slots: diff --git a/GUI/View/Common/DoubleSpinBox.h b/GUI/View/Common/DoubleSpinBox.h index 5a298fde617b89d94cf126349eaad2df5da25b65..ee036ebefa72f98d99714f82e2583ffe7c981cf4 100644 --- a/GUI/View/Common/DoubleSpinBox.h +++ b/GUI/View/Common/DoubleSpinBox.h @@ -47,7 +47,7 @@ public: //! Returns the unit of the contained DoubleProperty. //! //! If the unit is defined as a string, this method returns Unit::other. To get the string, use - //! valueDescriptor().unit + //! valueProperty().unit Unit baseUnit() const; //! Update the shown value to the one contained in the value descriptor. @@ -58,7 +58,7 @@ public: signals: //! Emitted whenever the value changes. //! - //! newBaseValue is in the unit of the valueDescriptor. + //! newBaseValue is in the unit of the valueProperty. void baseValueChanged(double newBaseValue); protected: diff --git a/GUI/View/Instrument/DetectorEditor.cpp b/GUI/View/Instrument/DetectorEditor.cpp index 7ecdb9455ddd2f23307a331cf6a837b3701962fa..1b3eec2bdc37a2ccdb3cd370a28ac4364bd64537 100644 --- a/GUI/View/Instrument/DetectorEditor.cpp +++ b/GUI/View/Instrument/DetectorEditor.cpp @@ -31,7 +31,7 @@ DetectorEditor::DetectorEditor(QWidget* parent, Instrument2DItem* instrument) m_formLayout = new QFormLayout(this); auto* detectorTypeCombo = - GUI::Util::createComboBoxFromDescriptor(instrument->detectorSelection(), [=](int) { + GUI::Util::createComboBoxFromProperty(instrument->detector(), [=](int) { createDetectorWidgets(); emit dataChanged(); }); @@ -47,7 +47,7 @@ void DetectorEditor::createDetectorWidgets() while (m_formLayout->rowCount() > 1) m_formLayout->removeRow(1); - auto* detectorItem = m_instrument->detectorSelection().currentItem(); + auto* detectorItem = m_instrument->detectorItem(); if (auto* rect = dynamic_cast<RectangularDetectorItem*>(detectorItem)) { auto* editor = new RectangularDetectorEditor(this, rect); m_formLayout->addRow(editor); diff --git a/GUI/View/Instrument/DistributionEditor.cpp b/GUI/View/Instrument/DistributionEditor.cpp index 9c9116d32b3c8bceb1fc6167c3f3a4d9df8f2716..c9e866bb995786888a5834f1e69c6d876560336f 100644 --- a/GUI/View/Instrument/DistributionEditor.cpp +++ b/GUI/View/Instrument/DistributionEditor.cpp @@ -45,11 +45,10 @@ DistributionSelector::DistributionSelector(std::optional<MeanConfig> mean_config m_formLayout = new QFormLayout(this); m_formLayout->setContentsMargins(0, 0, 0, 0); - m_distributionCombo = - GUI::Util::createComboBoxFromDescriptor(item->distributionSelection(), [=](int) { - createDistributionWidgets(); - emit distributionChanged(); - }); + m_distributionCombo = GUI::Util::createComboBoxFromProperty(item->distribution(), [=](int) { + createDistributionWidgets(); + emit distributionChanged(); + }); m_formLayout->addRow("Distribution:", m_distributionCombo); createDistributionWidgets(); @@ -60,12 +59,12 @@ void DistributionSelector::createDistributionWidgets() while (m_formLayout->rowCount() > 1) m_formLayout->removeRow(1); - if (auto* cosine = dynamic_cast<DistributionCosineItem*>(m_item->distribution())) { + if (auto* cosine = dynamic_cast<DistributionCosineItem*>(m_item->distributionItem())) { createMeanSpinBox(cosine->mean()); createSpinBox(cosine->sigma()); createNumSamplesSpinBox(cosine); createSpinBox(cosine->sigmaFactor()); - } else if (auto* gate = dynamic_cast<DistributionGateItem*>(m_item->distribution())) { + } else if (auto* gate = dynamic_cast<DistributionGateItem*>(m_item->distributionItem())) { auto* minSpinbox = createSpinBox(gate->minimum()); auto* maxSpinbox = createSpinBox(gate->maximum()); connect(minSpinbox, &DoubleSpinBox::baseValueChanged, [=](double d) { @@ -81,24 +80,26 @@ void DistributionSelector::createDistributionWidgets() } }); createNumSamplesSpinBox(gate); - } else if (auto* gauss = dynamic_cast<DistributionGaussianItem*>(m_item->distribution())) { + } else if (auto* gauss = dynamic_cast<DistributionGaussianItem*>(m_item->distributionItem())) { createMeanSpinBox(gauss->mean()); createSpinBox(gauss->standardDeviation()); createNumSamplesSpinBox(gauss); createSpinBox(gauss->sigmaFactor()); - } else if (auto* logNormal = dynamic_cast<DistributionLogNormalItem*>(m_item->distribution())) { + } else if (auto* logNormal = + dynamic_cast<DistributionLogNormalItem*>(m_item->distributionItem())) { createSpinBox(logNormal->median()); createSpinBox(logNormal->scaleParameter()); createNumSamplesSpinBox(logNormal); createSpinBox(logNormal->sigmaFactor()); - } else if (auto* lorentz = dynamic_cast<DistributionLorentzItem*>(m_item->distribution())) { + } else if (auto* lorentz = dynamic_cast<DistributionLorentzItem*>(m_item->distributionItem())) { createMeanSpinBox(lorentz->mean()); createSpinBox(lorentz->hwhm()); createNumSamplesSpinBox(lorentz); createSpinBox(lorentz->sigmaFactor()); - } else if (auto* none = dynamic_cast<DistributionNoneItem*>(m_item->distribution())) { + } else if (auto* none = dynamic_cast<DistributionNoneItem*>(m_item->distributionItem())) { createMeanSpinBox(none->mean()); - } else if (auto* trapezoid = dynamic_cast<DistributionTrapezoidItem*>(m_item->distribution())) { + } else if (auto* trapezoid = + dynamic_cast<DistributionTrapezoidItem*>(m_item->distributionItem())) { createSpinBox(trapezoid->center()); createSpinBox(trapezoid->leftWidth()); createSpinBox(trapezoid->middleWidth()); @@ -156,7 +157,7 @@ GUI::ID::Distributions DistributionSelector::distributions() const void DistributionSelector::refresh() { QSignalBlocker b(m_distributionCombo); - m_distributionCombo->setCurrentIndex(m_item->distributionSelection().currentIndex()); + m_distributionCombo->setCurrentIndex(m_item->distribution().currentIndex()); createDistributionWidgets(); } @@ -200,7 +201,7 @@ void DistributionEditor::updateData() void DistributionEditor::updatePlot() { - auto* d = m_selector->item()->distribution(); + auto* d = m_selector->item()->distributionItem(); m_plot->setVisible(!dynamic_cast<const DistributionNoneItem*>(d)); m_plot->setDistItem(d); m_plot->plotItem(); diff --git a/GUI/View/Instrument/EnvironmentEditor.cpp b/GUI/View/Instrument/EnvironmentEditor.cpp index 514bfac3e490f246f6c94d3541f6242be3518ec8..a17f986e49b1d315be3c4b4350ffa2e98ef70ef4 100644 --- a/GUI/View/Instrument/EnvironmentEditor.cpp +++ b/GUI/View/Instrument/EnvironmentEditor.cpp @@ -29,7 +29,7 @@ EnvironmentEditor::EnvironmentEditor(QWidget* parent, InstrumentItem* instrument m_formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint); auto* backgroundTypeCombo = - GUI::Util::createComboBoxFromDescriptor(instrument->backgroundSelection(), [=](int) { + GUI::Util::createComboBoxFromProperty(instrument->background(), [=](int) { createBackgroundWidgets(); emit dataChanged(); }); @@ -44,7 +44,7 @@ void EnvironmentEditor::createBackgroundWidgets() while (m_formLayout->rowCount() > 1) m_formLayout->removeRow(1); - auto* backgroundItem = m_instrument->backgroundSelection().currentItem(); + auto* backgroundItem = m_instrument->backgroundItem(); if (auto* p = dynamic_cast<ConstantBackgroundItem*>(backgroundItem)) { auto* spinbox = new DoubleSpinBox(p->backgroundValue()); spinbox->setSingleStep(0.01); diff --git a/GUI/View/Instrument/FootprintCorrectionEditor.cpp b/GUI/View/Instrument/FootprintCorrectionEditor.cpp index 349034b05294d73dfeac22703e6e834f804179c1..859d2210a37ccb48aa368a01a9f4c28dd0737190 100644 --- a/GUI/View/Instrument/FootprintCorrectionEditor.cpp +++ b/GUI/View/Instrument/FootprintCorrectionEditor.cpp @@ -28,7 +28,7 @@ FootprintCorrectionEditor::FootprintCorrectionEditor(QWidget* parent, SpecularBe setProperty("subgroup", true); // for stylesheet addressing m_formLayout = new QFormLayout(this); m_formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint); - auto* typeCombo = GUI::Util::createComboBoxFromDescriptor(item->footprintSelection(), [=](int) { + auto* typeCombo = GUI::Util::createComboBoxFromProperty(item->footprint(), [=](int) { createFootprintWidgets(); emit dataChanged(); }); @@ -44,7 +44,7 @@ void FootprintCorrectionEditor::createFootprintWidgets() while (m_formLayout->rowCount() > 1) m_formLayout->removeRow(1); - auto* footprintItem = m_item->footprintSelection().currentItem(); + auto* footprintItem = m_item->footprint().currentItem(); if (auto* square = dynamic_cast<FootprintSquareItem*>(footprintItem)) { auto* spinbox = new DoubleSpinBox(square->squareFootprintValue()); spinbox->setSingleStep(0.01); diff --git a/GUI/View/Instrument/InclinationAnglesEditor.cpp b/GUI/View/Instrument/InclinationAnglesEditor.cpp index 50c837995cdecb18e8f559ad5661fa409ef8f02d..972d464298bccd68d245a5b16e757cd74dc84362 100644 --- a/GUI/View/Instrument/InclinationAnglesEditor.cpp +++ b/GUI/View/Instrument/InclinationAnglesEditor.cpp @@ -96,7 +96,7 @@ void InclinationAnglesEditor::onAxisTypeSelected(int index) void InclinationAnglesEditor::updatePlot() { - auto* d = m_selector->item()->distribution(); + auto* d = m_selector->item()->distributionItem(); m_plot->setVisible(!dynamic_cast<const DistributionNoneItem*>(d)); m_plot->setDistItem(d); m_plot->plotItem(); diff --git a/GUI/View/Instrument/ResolutionFunctionEditor.cpp b/GUI/View/Instrument/ResolutionFunctionEditor.cpp index 9d6f18ef2c084657f75a64ca3ba77c9bafef1aea..4518aac1a543ad1fc55a28aaaa042e75d5b650bb 100644 --- a/GUI/View/Instrument/ResolutionFunctionEditor.cpp +++ b/GUI/View/Instrument/ResolutionFunctionEditor.cpp @@ -31,11 +31,10 @@ ResolutionFunctionEditor::ResolutionFunctionEditor(Unit unit, QWidget* parent, D m_formLayout = new QFormLayout(this); m_formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint); - auto* typeCombo = - GUI::Util::createComboBoxFromDescriptor(item->resolutionFunctionSelection(), [=](int) { - createResolutionWidgets(); - emit dataChanged(); - }); + auto* typeCombo = GUI::Util::createComboBoxFromProperty(item->resolutionFunction(), [=](int) { + createResolutionWidgets(); + emit dataChanged(); + }); m_formLayout->addRow("Type:", typeCombo); GroupBoxCollapser::installIntoGroupBox(this); @@ -48,7 +47,7 @@ void ResolutionFunctionEditor::createResolutionWidgets() while (m_formLayout->rowCount() > 1) m_formLayout->removeRow(1); - auto* resFunction = m_item->resolutionFunctionSelection().currentItem(); + auto* resFunction = m_item->resolutionFunction().currentItem(); if (auto* p = dynamic_cast<ResolutionFunction2DGaussianItem*>(resFunction)) { auto* sigmaXSpinBox = GUI::Util::createDoubleSpinBoxRow(m_formLayout, p->sigmaX()); auto* sigmaYSpinBox = GUI::Util::createDoubleSpinBoxRow(m_formLayout, p->sigmaY()); diff --git a/GUI/View/SampleDesigner/CoreAndShellForm.cpp b/GUI/View/SampleDesigner/CoreAndShellForm.cpp index 6c38086b00cada5260040275707e1146a27f5477..1943c2c1f6cecff7b34ef10a386fcca4d336b118 100644 --- a/GUI/View/SampleDesigner/CoreAndShellForm.cpp +++ b/GUI/View/SampleDesigner/CoreAndShellForm.cpp @@ -69,7 +69,7 @@ CoreAndShellForm::CoreAndShellForm(QWidget* parent, CoreAndShellItem* item, core.layouter = std::make_unique<FormLayouter>(coreParticleGroup, ec); core.formfactorCombo = createFormFactorCombo( - coreParticleGroup, item->core() != nullptr ? item->core()->formfactor() : nullptr); + coreParticleGroup, item->core() != nullptr ? item->core()->formfactorItem() : nullptr); connect(core.formfactorCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CoreAndShellForm::onCoreComboChanged); core.layouter->addRow("Form factor:", core.formfactorCombo); @@ -92,7 +92,8 @@ CoreAndShellForm::CoreAndShellForm(QWidget* parent, CoreAndShellItem* item, shellParticleGroup->setObjectName("Particle"); shell.layouter = std::make_unique<FormLayouter>(shellParticleGroup, ec); shell.formfactorCombo = createFormFactorCombo( - shellParticleGroup, item->shell() != nullptr ? item->shell()->formfactor() : nullptr); + shellParticleGroup, + item->shell() != nullptr ? item->shell()->formfactorItem() : nullptr); connect(shell.formfactorCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CoreAndShellForm::onShellComboChanged); shell.layouter->addRow("Form factor:", shell.formfactorCombo); @@ -158,10 +159,11 @@ void CoreAndShellForm::createCoreWidgets() QString groupTitle = "Core"; if (ParticleItem* particle = m_item->core()) { - const QString formfactor = FormFactorItemCatalog::menuEntry(particle->formfactor()); + const QString formfactor = FormFactorItemCatalog::menuEntry(particle->formfactorItem()); groupTitle += " (" + formfactor + ")"; - core.layouter->addGroupOfValues("Geometry", particle->formfactor()->geometryProperties()); + core.layouter->addGroupOfValues("Geometry", + particle->formfactorItem()->geometryProperties()); core.layouter->addVector(particle->position(), false); core.layouter->addSelection(particle->rotation()); // no abundance since this is handled in CoreShell itself! @@ -175,10 +177,11 @@ void CoreAndShellForm::createShellWidgets() QString groupTitle = "Shell"; if (ParticleItem* particle = m_item->shell()) { - const QString formfactor = FormFactorItemCatalog::menuEntry(particle->formfactor()); + const QString formfactor = FormFactorItemCatalog::menuEntry(particle->formfactorItem()); groupTitle += " (" + formfactor + ")"; - shell.layouter->addGroupOfValues("Geometry", particle->formfactor()->geometryProperties()); + shell.layouter->addGroupOfValues("Geometry", + particle->formfactorItem()->geometryProperties()); shell.layouter->addSelection(particle->rotation()); // no position vector - not allowed in CoreShell // no abundance since this is handled in CoreShell itself! diff --git a/GUI/View/SampleDesigner/FormLayouter.h b/GUI/View/SampleDesigner/FormLayouter.h index 2d19425d1222915bd54a63dd63bba6eac82cb305..d98fb41e2ea3a970bcda1ccc06e9104689f6df97 100644 --- a/GUI/View/SampleDesigner/FormLayouter.h +++ b/GUI/View/SampleDesigner/FormLayouter.h @@ -15,7 +15,7 @@ #ifndef BORNAGAIN_GUI_VIEW_SAMPLEDESIGNER_FORMLAYOUTER_H #define BORNAGAIN_GUI_VIEW_SAMPLEDESIGNER_FORMLAYOUTER_H -#include "GUI/Model/Descriptor/SelectionDescriptor.h" +#include "GUI/Model/Descriptor/SelectionProperty.h" #include "GUI/View/SampleDesigner/SelectionContainerForm.h" #include <QFormLayout> @@ -84,7 +84,7 @@ public: //! For more details, see SelectionContainerForm. //! Returns the newly added row. template <typename T> - int addSelection(const SelectionDescriptor<T>& d); + int addSelection(SelectionProperty<T>& d); //! Adds a row with a bold printed label and a DoubleSpinBox. //! @@ -115,7 +115,7 @@ public: //! Same functionality as addValue(), please read there. void insertValue(int row, DoubleProperty& d, std::function<void(double)> onValueChange); - //! Adds a row with a bold printed label and a set of DoubleDescriptors. + //! Adds a row with a bold printed label and a set of DoubleProperties. //! //! The label describes the set of the DoubleProperties and is located in the first column of //! the layout. The DoubleSpinBoxes for each DoubleProperty are created as children of a newly @@ -160,10 +160,10 @@ private: }; template <typename T> -int FormLayouter::addSelection(const SelectionDescriptor<T>& d) +int FormLayouter::addSelection(SelectionProperty<T>& d) { auto* w = new SelectionContainerForm(m_formLayout->parentWidget(), d, m_ec); - return addRow(d.label, w); + return addRow(d.label(), w); } template <typename T> diff --git a/GUI/View/SampleDesigner/InterferenceForm.cpp b/GUI/View/SampleDesigner/InterferenceForm.cpp index a31b2d5f94bf2bc5194faaf850a80afddd29cb2f..4c8bb49cf3dd1b632623e48c320d8b1565d37e80 100644 --- a/GUI/View/SampleDesigner/InterferenceForm.cpp +++ b/GUI/View/SampleDesigner/InterferenceForm.cpp @@ -38,8 +38,8 @@ InterferenceForm::InterferenceForm(QWidget* parent, ParticleLayoutItem* layoutIt m_interferenceTypeCombo = new QComboBox(this); WheelEventEater::install(m_interferenceTypeCombo); - auto d = layoutItem->interference(); - m_interferenceTypeCombo->addItems(d.options); + const auto& d = layoutItem->interference(); + m_interferenceTypeCombo->addItems(d.options()); m_interferenceTypeCombo->setCurrentIndex(d.currentIndex()); m_interferenceTypeCombo->setMaxVisibleItems(m_interferenceTypeCombo->count()); m_interferenceTypeCombo->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); @@ -101,7 +101,7 @@ void InterferenceForm::createInterferenceWidgets() } else if (auto* itf = dynamic_cast<Interference2DLatticeItem*>(interference)) { layouter.addValue(itf->positionVariance()); auto* w = new LatticeTypeSelectionForm(this, itf, m_ec); - layouter.addRow(itf->latticeType().label, w); + layouter.addRow(itf->latticeType().label(), w); layouter.addSelection(itf->decayFunction()); } else if (auto* itf = dynamic_cast<InterferenceFinite2DLatticeItem*>(interference)) { layouter.addValue(itf->positionVariance()); @@ -123,14 +123,14 @@ void InterferenceForm::createInterferenceWidgets() "Domain size 2 in number of unit cells")); auto* w = new LatticeTypeSelectionForm(this, itf, m_ec); - layouter.addRow(itf->latticeType().label, w); + layouter.addRow(itf->latticeType().label(), w); } else if (auto* itf = dynamic_cast<Interference2DParacrystalItem*>(interference)) { layouter.addValue(itf->positionVariance()); layouter.addValue(itf->dampingLength()); layouter.addValue(itf->domainSize1()); layouter.addValue(itf->domainSize2()); auto* w = new LatticeTypeSelectionForm(this, itf, m_ec); - layouter.addRow(itf->latticeType().label, w); + layouter.addRow(itf->latticeType().label(), w); layouter.addSelection(itf->probabilityDistribution1()); layouter.addSelection(itf->probabilityDistribution2()); } diff --git a/GUI/View/SampleDesigner/LatticeTypeSelectionForm.cpp b/GUI/View/SampleDesigner/LatticeTypeSelectionForm.cpp index 6055e19267e59715898c4e526665ea85739451e3..277988b7e6b011a258f335427fde8572553f7703 100644 --- a/GUI/View/SampleDesigner/LatticeTypeSelectionForm.cpp +++ b/GUI/View/SampleDesigner/LatticeTypeSelectionForm.cpp @@ -30,13 +30,13 @@ LatticeTypeSelectionForm::LatticeTypeSelectionForm( void LatticeTypeSelectionForm::createContent() { auto* currentLatticeType = m_interferenceItem->latticeType().currentItem(); - const auto valueDescriptors = currentLatticeType->geometryValues(false); - const bool vertical = valueDescriptors.size() > 2; + const auto valueProperties = currentLatticeType->geometryValues(false); + const bool vertical = valueProperties.size() > 2; const auto onValueChange = [this](double newValue, DoubleProperty& d) { m_ec->setDensityRelatedValue(m_interferenceItem, newValue, d); }; - LayerEditorUtils::addMultiPropertyToGrid(m_gridLayout, 1, valueDescriptors, onValueChange, + LayerEditorUtils::addMultiPropertyToGrid(m_gridLayout, 1, valueProperties, onValueChange, vertical, false); m_integrateOverXiCheckBox = new QCheckBox("Integrate over Xi", this); diff --git a/GUI/View/SampleDesigner/LayerEditorUtils.cpp b/GUI/View/SampleDesigner/LayerEditorUtils.cpp index a332500f84d0100bf6435e5342fd47e7ab08ca72..37c355fcd301bb8056f71a25cab03ad5b6bc97a7 100644 --- a/GUI/View/SampleDesigner/LayerEditorUtils.cpp +++ b/GUI/View/SampleDesigner/LayerEditorUtils.cpp @@ -65,7 +65,7 @@ void LayerEditorUtils::updateLabelUnit(QLabel* label) } void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol, - const DoublePropertyRefs& valueDescriptors, + const DoublePropertyRefs& valueProperties, SampleEditorController* ec, bool vertically, bool addSpacer) { @@ -73,17 +73,17 @@ void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int fir ec->setDouble(newValue, d); }; - addMultiPropertyToGrid(m_gridLayout, firstCol, valueDescriptors, setNewValue, vertically, + addMultiPropertyToGrid(m_gridLayout, firstCol, valueProperties, setNewValue, vertically, addSpacer); } void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol, - const DoublePropertyRefs& valueDescriptors, + const DoublePropertyRefs& valueProperties, function<void(double, DoubleProperty&)> setNewValue, bool vertically, bool addSpacer) { int col = firstCol; - for (DoubleProperty& d : valueDescriptors) { + for (DoubleProperty& d : valueProperties) { DoubleSpinBox* editor; if (d.label() == "Angle") editor = new DoubleSpinBox(d, false, 1, 1.0); @@ -114,11 +114,11 @@ void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int fir } void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol, - const DoublePropertyRefs& valueDescriptors, + const DoublePropertyRefs& valueProperties, SampleEditorController* ec, bool addSpacer) { - addMultiPropertyToGrid(m_gridLayout, firstCol, valueDescriptors, ec, - valueDescriptors.size() > 1, addSpacer); + addMultiPropertyToGrid(m_gridLayout, firstCol, valueProperties, ec, valueProperties.size() > 1, + addSpacer); } void LayerEditorUtils::addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, VectorProperty& v, @@ -150,31 +150,35 @@ DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(RotationItem* item) { if (!item) return {}; - return item->rotationProperties(); } DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(Profile2DItem* item) { + if (!item) + return {}; return item->profileProperties(); } DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(Profile1DItem* item) { + if (!item) + return {}; return item->profileProperties(); } DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(FormFactorItem* item) { + if (!item) + return {}; return item->geometryProperties(); } -DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(RoughnessItem* r) +DoublePropertyRefs LayerEditorUtils::doublePropertiesOfItem(RoughnessItem* item) { - if (!r) + if (!item) return {}; - - return r->roughnessProperties(); + return item->roughnessProperties(); } QWidget* LayerEditorUtils::createWidgetForItemWithParticles(QWidget* parentWidget, diff --git a/GUI/View/SampleDesigner/LayerEditorUtils.h b/GUI/View/SampleDesigner/LayerEditorUtils.h index eadd0180559fddba8db2c032099c1bd99d8faf2c..9e7c88cddc6f8190e0e0d1271147ad342ba204aa 100644 --- a/GUI/View/SampleDesigner/LayerEditorUtils.h +++ b/GUI/View/SampleDesigner/LayerEditorUtils.h @@ -43,28 +43,28 @@ namespace LayerEditorUtils { void updateLabelUnit(QLabel* label); void updateLabelUnit(QLabel* label, DoubleSpinBox* editor); -//! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to +//! Create DoubleSpinBoxes for the DoubleProperties and connect them to //! SampleEditorController::setDouble() void addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol, - const DoublePropertyRefs& valueDescriptors, SampleEditorController* ec, + const DoublePropertyRefs& valueProperties, SampleEditorController* ec, bool vertically, bool addSpacer); -//! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to the given setNewValue() +//! Create DoubleSpinBoxes for the DoubleProperties and connect them to the given setNewValue() void addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol, - const DoublePropertyRefs& valueDescriptors, + const DoublePropertyRefs& valueProperties, std::function<void(double, DoubleProperty&)> setNewValue, bool vertically, bool addSpacer); void addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol, - const DoublePropertyRefs& valueDescriptors, SampleEditorController* ec, + const DoublePropertyRefs& valueProperties, SampleEditorController* ec, bool addSpacer); -//! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to +//! Create DoubleSpinBoxes for the DoubleProperties and connect them to //! SampleEditorController::setDouble() void addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, VectorProperty& v, SampleEditorController* ec, bool vertically, bool addSpacer); -//! Create DoubleSpinBoxes for the DoubeDescriptors and connect them to the given setNewValue() +//! Create DoubleSpinBoxes for the DoubleProperties and connect them to the given setNewValue() void addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, VectorProperty& v, std::function<void(double, DoubleProperty&)> setNewValue, bool vertically, bool addSpacer); diff --git a/GUI/View/SampleDesigner/MesocrystalForm.cpp b/GUI/View/SampleDesigner/MesocrystalForm.cpp index 2e35b64ccafc699788dfc3811d586b56e8b39684..8a13ad160f69b8b689274d05e12927a9142a3330 100644 --- a/GUI/View/SampleDesigner/MesocrystalForm.cpp +++ b/GUI/View/SampleDesigner/MesocrystalForm.cpp @@ -72,7 +72,7 @@ QComboBox* MesocrystalForm::createBasisCombo(QWidget* parent, ItemWithParticles* const auto ui = FormFactorItemCatalog::uiInfo(type); combo->addItem(QIcon(ui.iconPath), ui.menuEntry, static_cast<uint32_t>(type)); if (auto* p = dynamic_cast<ParticleItem*>(current)) - if (FormFactorItemCatalog::type(p->formfactor()) == type) + if (FormFactorItemCatalog::type(p->formfactorItem()) == type) currentData = static_cast<uint32_t>(type); } for (auto type : ItemWithParticlesCatalog::assemblyTypes()) { diff --git a/GUI/View/SampleDesigner/ParticleForm.cpp b/GUI/View/SampleDesigner/ParticleForm.cpp index 5a12035217fc51173af451d2adac89a9db7214b1..7a726cb20353e9b9a068e3e43a5e9e37f6786c40 100644 --- a/GUI/View/SampleDesigner/ParticleForm.cpp +++ b/GUI/View/SampleDesigner/ParticleForm.cpp @@ -26,12 +26,12 @@ ParticleForm::ParticleForm(QWidget* parent, ParticleItem* particleItem, bool all SampleEditorController* ec, bool allowRemove) : QGroupBox(parent) { - const QString formfactor = FormFactorItemCatalog::menuEntry(particleItem->formfactor()); + const QString formfactor = FormFactorItemCatalog::menuEntry(particleItem->formfactorItem()); setTitle("Particle (" + formfactor + ")"); FormLayouter layouter(this, ec); layouter.addRow("Material", new MaterialInplaceForm(this, particleItem, ec)); - layouter.addGroupOfValues("Geometry", particleItem->formfactor()->geometryProperties()); + layouter.addGroupOfValues("Geometry", particleItem->formfactorItem()->geometryProperties()); layouter.addVector(particleItem->position(), false); layouter.addSelection(particleItem->rotation()); if (allowAbundance) diff --git a/GUI/View/SampleDesigner/SampleEditorController.cpp b/GUI/View/SampleDesigner/SampleEditorController.cpp index 4edca089d2a80914f63e2292e130494d2d6a7a26..e35898f0cd773cd8cb86491ba713944b825b1573 100644 --- a/GUI/View/SampleDesigner/SampleEditorController.cpp +++ b/GUI/View/SampleDesigner/SampleEditorController.cpp @@ -340,7 +340,7 @@ void SampleEditorController::setDoubleFromUndo(double newValue, const QString& p } void SampleEditorController::setCurrentIndex(AbstractSelectionContainerForm* widget, int index, - const AbstractSelectionDescriptor& d) + AbstractSelectionProperty& d) { d.setCurrentIndex(index); widget->createContent(); @@ -400,7 +400,7 @@ void SampleEditorController::setDensityRelatedValue(InterferenceItem* interferen // -- notify the containing particle layout UI about changed value ASSERT(m_sampleForm); for (auto* c : m_sampleForm->findChildren<ParticleLayoutForm*>()) - if (c->layoutItem()->interference() == interferenceItem) { + if (c->layoutItem()->interference().currentItem() == interferenceItem) { c->updateDensityValue(); break; } diff --git a/GUI/View/SampleDesigner/SampleEditorController.h b/GUI/View/SampleDesigner/SampleEditorController.h index c73e5cc195367339add35264ff1441e94e51f623..ac243dcc9ef0271bcd5f996c52718821490aa6b9 100644 --- a/GUI/View/SampleDesigner/SampleEditorController.h +++ b/GUI/View/SampleDesigner/SampleEditorController.h @@ -20,7 +20,7 @@ #include <QUndoStack> class AbstractSelectionContainerForm; -class AbstractSelectionDescriptor; +class AbstractSelectionProperty; class CompoundItem; class CoreAndShellForm; class DoubleProperty; @@ -94,7 +94,7 @@ public: void setDoubleFromUndo(double newValue, const QString& path); void setCurrentIndex(AbstractSelectionContainerForm* widget, int index, - const AbstractSelectionDescriptor& d); + AbstractSelectionProperty& d); void selectMaterial(ItemWithMaterial* item, const QString& newMaterialIdentifier); void setMaterialValue(ItemWithMaterial* item, double newValue, DoubleProperty& d); diff --git a/GUI/View/SampleDesigner/SelectionContainerForm.h b/GUI/View/SampleDesigner/SelectionContainerForm.h index e4e8af4cacf2de6e309c5d98b8507333d3f63e1b..dba2787d85aff4c73b195510317a9400a94ad3b7 100644 --- a/GUI/View/SampleDesigner/SelectionContainerForm.h +++ b/GUI/View/SampleDesigner/SelectionContainerForm.h @@ -39,7 +39,7 @@ protected: } template <typename T> - void initUI(const SelectionDescriptor<T>& d) + void initUI(SelectionProperty<T>& d) { m_gridLayout = new QGridLayout(this); m_gridLayout->setContentsMargins(0, 0, 0, 0); @@ -47,12 +47,12 @@ protected: m_combo = new QComboBox; WheelEventEater::install(m_combo); - m_combo->addItems(d.options); + m_combo->addItems(d.options()); m_combo->setCurrentIndex(d.currentIndex()); m_combo->setMaxVisibleItems(m_combo->count()); QObject::connect(m_combo, QOverload<int>::of(&QComboBox::currentIndexChanged), - [=](int current) { + [this, &d](int current) { clear(); m_ec->setCurrentIndex(this, current, d); }); @@ -62,7 +62,7 @@ protected: } private: - //! Remove all descriptors from the layout + //! Remove all properties from the layout void clear() { auto* layoutItemOfComboBox = m_gridLayout->itemAtPosition(1, 0); @@ -77,22 +77,23 @@ protected: SampleEditorController* m_ec; }; -//! A widget to contain a selection, defined by a SelectionDescriptor. +//! A widget to contain a selection, defined by a SelectionProperty. //! //! This SelectionContainerForm is limited to contain the selection combo box and a list of double -//! values represented by DoubleDescriptors. The list of DoubleDescriptors is queried by calling -//! LayerEditorUtils::doubleDescriptorsOfItem(). To have the correct DoubleDescriptors on this form, +//! values represented by DoubleProperties. The list of DoubleProperties is queried by calling +//! LayerEditorUtils::doublePropertiesOfItem(). To have the correct DoubleProperties on this form, //! you may have to overload this method according to your class and your needs. The overload will -//! expect the template type you defined for SelectionDescriptor. +//! expect the template type you defined for SelectionProperty. //! //! Example: -//! SelectionDescriptor<RotationItem*> => LayerEditorUtils::doubleDescriptorsOfItem(RotationItem*) +//! SelectionProperty<RotationItemCatalog> => +//! LayerEditorUtils::doublePropertiesOfItem(RotationItem*) //! -//! The connection from selection combo -> SelectionDescriptor is made via +//! The connection from selection combo -> SelectionProperty is made via //! SampleEditorController::setCurrentIndex(), where a command can be used for undo purposes. //! -//! For each DoubleDescriptor, a unit-aware DoubleSpinBox is created. The connection from each -//! spinbox to the DoubleDescriptor is made via SampleEditorController::setDouble(), where a command +//! For each DoubleProperty, a unit-aware DoubleSpinBox is created. The connection from each +//! spinbox to the DoubleProperty is made via SampleEditorController::setDouble(), where a command //! can be used for undo purposes. //! //! If a more complex selection shall be realized (e.g. with @@ -100,17 +101,10 @@ protected: class SelectionContainerForm : public AbstractSelectionContainerForm { public: template <typename T> - SelectionContainerForm(QWidget* parent, const SelectionDescriptor<T>& d, - SampleEditorController* ec) + SelectionContainerForm(QWidget* parent, SelectionProperty<T>& d, SampleEditorController* ec) : AbstractSelectionContainerForm(parent, ec) { - if (d.currentItem != nullptr) - currentValues = [=] { - return LayerEditorUtils::doublePropertiesOfItem(d.currentItem()); - }; - else - currentValues = [] { return DoublePropertyRefs(); }; - + currentValues = [&d] { return LayerEditorUtils::doublePropertiesOfItem(d.currentItem()); }; initUI(d); } diff --git a/GUI/View/Tool/WidgetUtils.cpp b/GUI/View/Tool/WidgetUtils.cpp index 2888eeb8b3d2f589a56ff7142febae33664b73af..a1152172f6a617312dc14d2fe1a5298991888dbe 100644 --- a/GUI/View/Tool/WidgetUtils.cpp +++ b/GUI/View/Tool/WidgetUtils.cpp @@ -13,6 +13,7 @@ // ************************************************************************************************ #include "GUI/View/Tool/WidgetUtils.h" +#include "GUI/Util/ComboProperty.h" #include "GUI/View/Common/DoubleSpinBox.h" #include "GUI/View/Common/ScientificSpinBox.h" #include "GUI/View/Tool/EditUtil.h" diff --git a/GUI/View/Tool/WidgetUtils.h b/GUI/View/Tool/WidgetUtils.h index 5e514927a9056ac18a15f78cb6c8266538229a3c..8c1b8b6c7b99fe5860a3a4e41c6898671f4bb545 100644 --- a/GUI/View/Tool/WidgetUtils.h +++ b/GUI/View/Tool/WidgetUtils.h @@ -16,12 +16,13 @@ #define BORNAGAIN_GUI_VIEW_TOOL_WIDGETUTILS_H #include "Fit/Param/RealLimits.h" -#include "GUI/Model/Descriptor/SelectionDescriptor.h" +#include "GUI/Model/Descriptor/SelectionProperty.h" #include "GUI/Support/Type/Unit.h" #include "GUI/View/Common/CustomEventFilters.h" #include <QComboBox> #include <variant> +class ComboProperty; class QSpinBox; class QCheckBox; class DoubleSpinBox; @@ -51,7 +52,7 @@ QComboBox* createSafeComboBox(std::function<ComboProperty()> comboFunction, QList<std::function<void()>>* updaters = nullptr, QString tooltip = ""); -//! Create a combo box with the information found in a selection descriptor. +//! Create a combo box with the information found in a selection property. //! //! The combo will be filled with the available options and will get the found tooltip. //! The current index will be set according to the current index in the selection. @@ -59,38 +60,29 @@ QComboBox* createSafeComboBox(std::function<ComboProperty()> comboFunction, //! would be dangerous if the combo is on a scrollable form - unintended and unnoticed changes would //! take place when just scrolling through the form. //! -//! Changes in the combobox will be notified to the SelectionDescriptor already. The additional (and +//! Changes in the combobox will be notified to the SelectionProperty already. The additional (and //! optional) slot can be used to be notified about an already executed change. //! -//! The combo can be updated from outside using "updaters" list. -//! template <typename T> -QComboBox* createComboBoxFromDescriptor(SelectionDescriptor<T> d, - std::function<void(int)> slot = nullptr, - QList<std::function<void()>>* updaters = nullptr, - bool isScrollable = false) +QComboBox* createComboBoxFromProperty(SelectionProperty<T>& d, + std::function<void(int)> slot = nullptr, + bool isScrollable = false) { QComboBox* combo = new QComboBox; - combo->addItems(d.options); - combo->setMaxCount(d.options.size()); - combo->setToolTip(d.tooltip); + combo->addItems(d.options()); + combo->setMaxCount(d.options().size()); + combo->setToolTip(d.tooltip()); combo->setCurrentIndex(d.currentIndex()); if (!isScrollable) WheelEventEater::install(combo); - QObject::connect(combo, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) { + QObject::connect(combo, qOverload<int>(&QComboBox::currentIndexChanged), [&d, slot](int index) { d.setCurrentIndex(index); if (slot) slot(index); }); - if (updaters) - (*updaters) << [=]() { - QSignalBlocker b(combo); - combo->setCurrentIndex(d.currentIndex()); - }; - return combo; } diff --git a/Tests/Unit/GUI/TestDetectorItems.cpp b/Tests/Unit/GUI/TestDetectorItems.cpp index 7904bb781c57c91a412a89ed084f05fa62518e22..2f22a28f1f1ccd850dbf391ddba68bcc37f988ca 100644 --- a/Tests/Unit/GUI/TestDetectorItems.cpp +++ b/Tests/Unit/GUI/TestDetectorItems.cpp @@ -41,7 +41,7 @@ TEST_F(TestDetectorItems, resolutionFunctionUnit) detector.setResolutionFunctionType<ResolutionFunctionNoneItem>(); detector.setResolutionFunctionType<ResolutionFunction2DGaussianItem>(); auto* p = dynamic_cast<ResolutionFunction2DGaussianItem*>( - detector.resolutionFunctionSelection().currentItem()); + detector.resolutionFunction().currentItem()); EXPECT_NE(p, nullptr); EXPECT_EQ(asString(p->sigmaX().unit()), "mm"); EXPECT_EQ(asString(p->sigmaY().unit()), "mm"); @@ -50,7 +50,7 @@ TEST_F(TestDetectorItems, resolutionFunctionUnit) sphericalDetector.setResolutionFunctionType<ResolutionFunctionNoneItem>(); sphericalDetector.setResolutionFunctionType<ResolutionFunction2DGaussianItem>(); p = dynamic_cast<ResolutionFunction2DGaussianItem*>( - sphericalDetector.resolutionFunctionSelection().currentItem()); + sphericalDetector.resolutionFunction().currentItem()); EXPECT_NE(p, nullptr); EXPECT_EQ(asString(p->sigmaX().unit()), unitAsString(Unit::degree)); EXPECT_EQ(asString(p->sigmaY().unit()), unitAsString(Unit::degree));