Skip to content
Snippets Groups Projects
InterferenceForm.cpp 5.44 KiB
Newer Older
  • Learn to ignore specific revisions
  • //  ************************************************************************************************
    //
    //  BornAgain: simulate and fit reflection and scattering
    //
    
    //! @file      GUI/View/SampleDesigner/InterferenceForm.cpp
    
    //! @brief     Implements class InterferenceForm
    //!
    //! @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/View/SampleDesigner/InterferenceForm.h"
    
    #include "GUI/Model/Item/InterferenceItems.h"
    #include "GUI/Model/Item/Lattice2DItems.h"
    #include "GUI/Model/Item/ParticleLayoutItem.h"
    
    #include "GUI/Model/Descriptor/UIntDescriptor.h"
    
    #include "GUI/View/PropertyEditor/CustomEventFilters.h"
    
    #include "GUI/View/SampleDesigner/FormLayouter.h"
    
    #include "GUI/View/SampleDesigner/LatticeTypeSelectionForm.h"
    
    #include "GUI/View/SampleDesigner/SampleEditorController.h"
    #include "GUI/View/SampleDesigner/SelectionContainerForm.h"
    
    #include "GUI/View/Tool/GroupBoxCollapser.h"
    
    
    InterferenceForm::InterferenceForm(QWidget* parent, ParticleLayoutItem* layoutItem,
                                       SampleEditorController* ec)
    
        : QGroupBox(parent)
        , m_layoutItem(layoutItem)
        , m_ec(ec)
    
    {
        setTitle("Interference Function");
    
        FormLayouter layouter(this, ec);
        layouter.setContentsMargins(6, 6, 0, 6);
        m_collapser = GroupBoxCollapser::installIntoGroupBox(this);
    
        m_interferenceTypeCombo = new QComboBox(this);
    
        WheelEventEater::install(m_interferenceTypeCombo);
    
        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);
        layouter.addRow("Type:", m_interferenceTypeCombo);
    
        createInterferenceWidgets();
    
        updateTitle();
    
        connect(m_interferenceTypeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
                [=](int newIndex) { m_ec->selectInterference(this, newIndex); });
    }
    
    ParticleLayoutItem* InterferenceForm::layoutItem() const
    {
        return m_layoutItem;
    
    void InterferenceForm::onInterferenceTypeChanged()
    
    {
        FormLayouter layouter(this, m_ec);
        while (layouter.layout()->rowCount() > 1)
            layouter.layout()->removeRow(1);
    
        createInterferenceWidgets();
        updateTitle();
    }
    
    void InterferenceForm::createInterferenceWidgets()
    {
        FormLayouter layouter(this, m_ec);
        auto* interference = m_layoutItem->interference().currentItem();
    
    
        // Some values in interference settings affect the total density in the particle layout. To
        // provide all the updating (data & UI), the method
        // SampleEditorController::setDensityRelatedValueValue has to be called (instead of
        // SampleEditorController::setDouble). For this we have the following lambda to add a value:
        const auto addDensityRelatedValue = [&](DoubleDescriptor d) {
            layouter.addValue(
                d, [=](double newValue) { m_ec->setDensityRelatedValue(interference, newValue, d); });
        };
    
    
        if (auto* itf = dynamic_cast<Interference1DLatticeItem*>(interference)) {
    
            layouter.addValue(itf->positionVariance());
            layouter.addValue(itf->length());
            layouter.addValue(itf->rotationAngle());
            layouter.addSelection(itf->decayFunction());
    
        } else if (auto* itf = dynamic_cast<InterferenceRadialParaCrystalItem*>(interference)) {
    
            layouter.addValue(itf->positionVariance());
            layouter.addValue(itf->peakDistance());
            layouter.addValue(itf->dampingLength());
            layouter.addValue(itf->domainSize());
            layouter.addValue(itf->kappa());
            layouter.addSelection(itf->probabilityDistribution());
    
        } else if (auto* itf = dynamic_cast<InterferenceHardDiskItem*>(interference)) {
    
            layouter.addValue(itf->positionVariance());
            layouter.addValue(itf->radius());
    
            addDensityRelatedValue(itf->density());
    
        } 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.addSelection(itf->decayFunction());
    
        } else if (auto* itf = dynamic_cast<InterferenceFinite2DLatticeItem*>(interference)) {
    
            layouter.addValue(itf->positionVariance());
            layouter.addValue(itf->domainSize1());
            layouter.addValue(itf->domainSize2());
            auto* w = new LatticeTypeSelectionForm(this, itf, m_ec);
            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.addSelection(itf->probabilityDistribution1());
            layouter.addSelection(itf->probabilityDistribution2());
    
        }
    }
    
    void InterferenceForm::updateTitle()
    {
        m_collapser->setTitle("Interference Function (" + m_interferenceTypeCombo->currentText() + ")");
    }