From bb99d195082fe6ea8f47c1e91fab36536f768994 Mon Sep 17 00:00:00 2001 From: Matthias Puchner <github@mpuchner.de> Date: Sat, 18 Dec 2021 09:02:19 +0100 Subject: [PATCH] free ItemWithParticles from SessionItem --- GUI/Model/Sample/ItemWithParticles.cpp | 133 +++--------------- GUI/Model/Sample/ItemWithParticles.h | 51 +++---- GUI/Model/Sample/ItemWithParticlesCatalog.cpp | 84 +++++++++++ GUI/Model/Sample/ItemWithParticlesCatalog.h | 55 ++++++++ 4 files changed, 175 insertions(+), 148 deletions(-) create mode 100644 GUI/Model/Sample/ItemWithParticlesCatalog.cpp create mode 100644 GUI/Model/Sample/ItemWithParticlesCatalog.h diff --git a/GUI/Model/Sample/ItemWithParticles.cpp b/GUI/Model/Sample/ItemWithParticles.cpp index 7d83a527051..ac4423b69cd 100644 --- a/GUI/Model/Sample/ItemWithParticles.cpp +++ b/GUI/Model/Sample/ItemWithParticles.cpp @@ -7,161 +7,66 @@ //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @copyright Forschungszentrum Jülich GmbH 2021 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) // // ************************************************************************************************ #include "GUI/Model/Sample/ItemWithParticles.h" #include "Base/Vector/RotMatrix.h" -#include "GUI/Model/Session/SessionItemUtils.h" -#include "GUI/Model/Session/SessionModel.h" -#include "GUI/Model/Trafo/RotationItems.h" -#include "GUI/Model/Trafo/TransformationItem.h" -#include "GUI/Model/Types/VectorDescriptor.h" -#include "MesoCrystalItem.h" -#include "ParticleCompositionItem.h" -#include "ParticleCoreShellItem.h" +#include "GUI/Model/Sample/RotationItemCatalog.h" #include "Sample/Particle/IParticle.h" #include "Sample/Scattering/Rotations.h" -DoubleDescriptor ItemWithParticles::abundance() const -{ - return DoubleDescriptor(getItem(P_ABUNDANCE), Unit::unitless); -} - -void ItemWithParticles::setAbundance(const double abundance) -{ - setItemValue(P_ABUNDANCE, abundance); -} -SessionItem* ItemWithParticles::abundanceItem() const +ItemWithParticles::ItemWithParticles(const QString& abundanceTooltip, + const QString& positionTooltip) { - return getItem(P_ABUNDANCE); + m_abundance.init("Abundance", abundanceTooltip, 1.0, Unit::unitless, 3, + RealLimits::limited(0.0, 1.0), "abundance"); + m_position.init("Position Offset", positionTooltip, Unit::nanometer, "pos"); + m_rotation.init<RotationItemCatalog>("Rotation", "", "rotation"); } -void ItemWithParticles::enableAbundance(bool b) +DoubleDescriptor ItemWithParticles::abundance() const { - getItem(P_ABUNDANCE)->setEnabled(b); + return m_abundance; } -bool ItemWithParticles::parentHasOwnAbundance() const +void ItemWithParticles::setAbundance(const double abundance) { - return dynamic_cast<ParticleCoreShellItem*>(parent()) - || dynamic_cast<ParticleCompositionItem*>(parent()) - || dynamic_cast<MesoCrystalItem*>(parent()); + m_abundance.set(abundance); } R3 ItemWithParticles::position() const { - return item<VectorItem>(P_POSITION)->getVector(); + return m_position; } void ItemWithParticles::setPosition(const R3& position) { - item<VectorItem>(P_POSITION)->setVector(position); + m_position.set(position); } VectorDescriptor ItemWithParticles::positionVector() const { - return VectorDescriptor(item<VectorItem>(P_POSITION), Unit::nanometer); -} - -VectorItem* ItemWithParticles::positionItem() const -{ - return item<VectorItem>(P_POSITION); -} - -TransformationItem* ItemWithParticles::createTransformationItem() -{ - return model()->insertItem<TransformationItem>(this, -1, T_TRANSFORMATION); -} - -void ItemWithParticles::setTransformation(RotationItem* transformation) -{ - model()->moveItem(transformation, this, -1, T_TRANSFORMATION); -} - -RotationItem* ItemWithParticles::rotationItem() const -{ - auto* transformationItem = dynamic_cast<TransformationItem*>(getItem(T_TRANSFORMATION)); - return transformationItem ? transformationItem->rotationItem() : nullptr; -} - -bool ItemWithParticles::isTransformationTagName(const QString& name) -{ - return name == T_TRANSFORMATION; -} - -RotMatrix ItemWithParticles::rotation() const -{ - auto* const item = rotationItem(); - return item ? item->rotation() : RotMatrix(); + return m_position; } SelectionDescriptor<RotationItem*> ItemWithParticles::rotationMethod() { - SelectionDescriptor<RotationItem*> d; - - // we need a special filling for this selection descriptor (not just from a GroupItem), since - // the rotation is stored in a TransformationItem instance, which can be present or not. - - static QVector<QPair<QString, QString>> map = {{"None", ""}, - {"X axis Rotation", XRotationItem::M_TYPE}, - {"Y axis Rotation", YRotationItem::M_TYPE}, - {"Z axis Rotation", ZRotationItem::M_TYPE}, - {"Euler Rotation", EulerRotationItem::M_TYPE}}; - - d.label = "Rotation"; - - for (auto [title, type] : map) - d.options << title; - - d.currentItem = [=]() -> RotationItem* { return rotationItem(); }; - - d.currentIndexSetter = [=](int current) { - if (auto* item = getItem(T_TRANSFORMATION)) - model()->removeItem(item); - if (current > 0) - createTransformationItem()->setRotationType(map[current].second); - }; - - d.currentIndexGetter = [=]() { - auto* item = rotationItem(); - if (item == nullptr) - return 0; - for (int i = 1; i < map.size(); i++) - if (map[i].second == item->modelType()) - return i; - - return 0; - }; - - return d; -} - -ItemWithParticles::ItemWithParticles(const QString& model_type, const QString& abundance_tooltip, - const QString& position_tooltip) - : SessionItem(model_type) -{ - addProperty(P_ABUNDANCE, 1.0) - ->setLimits(RealLimits::limited(0.0, 1.0)) - .setDecimals(3) - .setToolTip(abundance_tooltip); - addProperty<VectorItem>(P_POSITION)->setToolTip(position_tooltip); - - registerTag(T_TRANSFORMATION, 0, 1, {TransformationItem::M_TYPE}); + return m_rotation; } -void ItemWithParticles::setDefaultTagTransformation() +void ItemWithParticles::setRotation(RotationItem* p) { - setDefaultTag(T_TRANSFORMATION); + m_rotation.set(p); } void ItemWithParticles::setTransformationInfo(IParticle* result) const { result->setParticlePosition(position()); - const RotMatrix r = rotation(); + const RotMatrix r = m_rotation.get() ? m_rotation.get()->rotation() : RotMatrix(); if (!r.isIdentity()) { std::unique_ptr<IRotation> rotation(IRotation::createRotation(r)); result->setRotation(*rotation); diff --git a/GUI/Model/Sample/ItemWithParticles.h b/GUI/Model/Sample/ItemWithParticles.h index 0c19710c7e9..8ec9eb4a509 100644 --- a/GUI/Model/Sample/ItemWithParticles.h +++ b/GUI/Model/Sample/ItemWithParticles.h @@ -7,7 +7,7 @@ //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @copyright Forschungszentrum Jülich GmbH 2021 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) // // ************************************************************************************************ @@ -15,50 +15,32 @@ #ifndef BORNAGAIN_GUI_MODEL_SAMPLE_ITEMWITHPARTICLES_H #define BORNAGAIN_GUI_MODEL_SAMPLE_ITEMWITHPARTICLES_H -#include "GUI/Model/Group/SelectionDescriptor.h" -#include "GUI/Model/Session/SessionItem.h" -#include <heinz/Vectors3D.h> +#include "GUI/Model/Sample/RotationItems.h" +#include "GUI/Model/Types/DoubleProperty.h" +#include "GUI/Model/Types/SelectionProperty.h" +#include "GUI/Model/Types/VectorProperty.h" -class DoubleDescriptor; class IParticle; -class IRotation; -class RotationItem; class RotMatrix; -class TransformationItem; -class VectorDescriptor; -class VectorItem; - -class ItemWithParticles : public virtual SessionItem { -private: - static constexpr auto P_ABUNDANCE{"Abundance"}; - static constexpr auto P_POSITION{"Position Offset"}; - static constexpr auto T_TRANSFORMATION{"Transformation Tag"}; +class ItemWithParticles { public: + virtual ~ItemWithParticles() = default; DoubleDescriptor abundance() const; void setAbundance(double abundance); - SessionItem* abundanceItem() const; - bool parentHasOwnAbundance() const; - - // #baMigration Use only while not migrated from SessionModel! - void enableAbundance(bool b); R3 position() const; void setPosition(const R3& position); VectorDescriptor positionVector() const; - VectorItem* positionItem() const; - - TransformationItem* createTransformationItem(); - void setTransformation(RotationItem* transformation); - static bool isTransformationTagName(const QString& name); - - //! Returns identity transformation if no rotation is defined at all - RotMatrix rotation() const; //! Returns selection descriptor for rotation methods. SelectionDescriptor<RotationItem*> rotationMethod(); - void setTransformationInfo(IParticle* result) const; + //! nullptr is allowed and sets to "no rotation" + void setRotation(RotationItem* p); + + void + setTransformationInfo(IParticle* result) const; // #baMigration rename; it's a getter/reader //! Return full hierarchical contained items with particles. //! @@ -66,15 +48,16 @@ public: virtual QVector<ItemWithParticles*> containedItemsWithParticles() const = 0; protected: - ItemWithParticles(const QString& model_type, const QString& abundance_tooltip, - const QString& position_tooltip); - - void setDefaultTagTransformation(); + ItemWithParticles(const QString& abundanceTooltip, const QString& positionTooltip); private: //! Convenience method to return a rotation item from the contained transformation item. //! nullptr, if no transformation item defined. RotationItem* rotationItem() const; + + DoubleProperty m_abundance; + VectorProperty m_position; + SelectionProperty<RotationItem*> m_rotation; }; #endif // BORNAGAIN_GUI_MODEL_SAMPLE_ITEMWITHPARTICLES_H diff --git a/GUI/Model/Sample/ItemWithParticlesCatalog.cpp b/GUI/Model/Sample/ItemWithParticlesCatalog.cpp new file mode 100644 index 00000000000..7a519735769 --- /dev/null +++ b/GUI/Model/Sample/ItemWithParticlesCatalog.cpp @@ -0,0 +1,84 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Model/Sample/ItemWithParticlesCatalog.cpp +//! @brief Implements class ItemWithParticlesCatalog +//! +//! @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) +// +// ************************************************************************************************ + +#include "GUI/Model/Sample/ItemWithParticlesCatalog.h" +#include "GUI/Model/Sample/MesoCrystalItem.h" +#include "GUI/Model/Sample/ParticleCompositionItem.h" +#include "GUI/Model/Sample/ParticleCoreShellItem.h" +#include "GUI/Model/Sample/ParticleItem.h" + +ItemWithParticles* ItemWithParticlesCatalog::create(Type type) +{ + switch (type) { + case Type::Particle: + return new ParticleItem(); + case Type::Composition: + return new ParticleCompositionItem(); + case Type::CoreShell: + return new ParticleCoreShellItem(); + case Type::MesoCrystal: + return new MesoCrystalItem(); + default: + ASSERT(false); + } +} + +QVector<ItemWithParticlesCatalog::Type> ItemWithParticlesCatalog::types() +{ + return {Type::Particle, Type::Composition, Type::CoreShell, Type::MesoCrystal}; +} + +ItemWithParticlesCatalog::UiInfo ItemWithParticlesCatalog::uiInfo(Type type) +{ + auto createUiInfo = [](const QString& menuEntry, const QString& iconName, + const QString& description) { + UiInfo info; + info.menuEntry = menuEntry; + info.iconPath = ":/SampleDesignerToolbox/images/" + iconName; + info.description = description; + return info; + }; + + switch (type) { + case Type::Particle: + return createUiInfo("Particle", "", ""); // particle is not on UI, only its form factor + case Type::Composition: + return createUiInfo("Particle Composition", "ParticleComposition_64x64.png", + "Composition of particles with fixed positions"); + case Type::CoreShell: + return createUiInfo("Core shell particle", "ParticleCoreShell_64x64.png", + "A particle with a core/shell geometry"); + case Type::MesoCrystal: + return createUiInfo("Meso Crystal", "Mesocrystal_64x64.png", + "A 3D crystal structure of nanoparticles"); + default: + ASSERT(false); + } +} + +ItemWithParticlesCatalog::Type ItemWithParticlesCatalog::type(ItemWithParticles* item) +{ + ASSERT(item); + + if (dynamic_cast<ParticleItem*>(item)) + return Type::Particle; + if (dynamic_cast<ParticleCompositionItem*>(item)) + return Type::Composition; + if (dynamic_cast<MesoCrystalItem*>(item)) + return Type::MesoCrystal; + if (dynamic_cast<ParticleCoreShellItem*>(item)) + return Type::CoreShell; + + ASSERT(false); +} diff --git a/GUI/Model/Sample/ItemWithParticlesCatalog.h b/GUI/Model/Sample/ItemWithParticlesCatalog.h new file mode 100644 index 00000000000..bcf7b60b7d5 --- /dev/null +++ b/GUI/Model/Sample/ItemWithParticlesCatalog.h @@ -0,0 +1,55 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Model/Sample/ItemWithParticlesCatalog.h +//! @brief Defines class ItemWithParticlesCatalog +//! +//! @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_SAMPLE_ITEMWITHPARTICLESCATALOG_H +#define BORNAGAIN_GUI_MODEL_SAMPLE_ITEMWITHPARTICLESCATALOG_H + +#include <QString> + +class ItemWithParticles; + +class ItemWithParticlesCatalog { +public: + using CatalogedType = ItemWithParticles; + + // Do not change the numbering! It is serialized! + enum class Type : uint8_t { Particle = 1, Composition = 2, CoreShell = 3, MesoCrystal = 4 }; + + struct UiInfo { + QString menuEntry; + QString description; + QString iconPath; + }; + + //! Creates the item of the given type. + //! + //! If type is "None", a nullptr is returned. + static ItemWithParticles* create(Type type); + + //! Available types of interference items. + //! + //! Contains also type "None". + //! This list is sorted as expected in the UI (e.g. in combo box) + static QVector<Type> types(); + + //! UiInfo on the given type. + static UiInfo uiInfo(Type t); + + //! Returns the enum type of the given item. + static Type type(ItemWithParticles* item); + + static QString menuEntry(ItemWithParticles* item); +}; + +#endif // BORNAGAIN_GUI_MODEL_SAMPLE_ITEMWITHPARTICLESCATALOG_H -- GitLab