Skip to content
Snippets Groups Projects
LayerForm.cpp 5.97 KiB
Newer Older
  • Learn to ignore specific revisions
  • //  ************************************************************************************************
    //
    //  BornAgain: simulate and fit reflection and scattering
    //
    
    //! @file      GUI/View/Sample/LayerForm.cpp
    
    //! @brief     Implements class LayerForm.
    
    //!
    //! @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/Sample/LayerForm.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "Base/Util/Assert.h"
    
    #include "Base/Util/Vec.h"
    
    #include "GUI/Model/Material/MaterialItem.h"
    
    #include "GUI/Model/Project/ProjectDocument.h"
    
    #include "GUI/Model/Sample/LayerItem.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "GUI/Model/Sample/RoughnessItems.h"
    
    #include "GUI/Model/Sample/SampleItem.h"
    
    #include "GUI/View/Numeric/NumWidgetUtil.h"
    
    #include "GUI/View/Sample/HeinzFormLayout.h"
    #include "GUI/View/Sample/MaterialInplaceForm.h"
    #include "GUI/View/Sample/ParticleLayoutForm.h"
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    #include "GUI/View/Sample/RoughnessForm.h"
    
    #include "GUI/View/Widget/WidgetMoverButton.h"
    
    #include <QLineEdit>
    #include <QPushButton>
    
    
    LayerForm::LayerForm(QWidget* parent, LayerItem* layer, SampleEditorController* ec)
    
        : LayerContainerForm(parent, layer, ec, "layer")
    
        m_layout->addBoldRow("Material:", new MaterialInplaceForm(layer, ec));
        m_layout->addValue(layer->thickness());
    
        m_thickness_row = m_layout->rowCount() - 1;
    
        m_layout->addBoldRow("Number of slices:", GUI::Util::createIntSpinBox(
    
                                                      [this] { return layerItem()->numSlices(); },
    
                                                      [this](int v) {
    
                                                          layerItem()->setNumSlices(v);
    
                                                          emit gDoc->sampleChanged();
    
                                                      },
                                                      RealLimits::lowerLimited(1),
                                                      "Number of horizontal slices.\n"
                                                      "Used for Average Layer Material calculations \n"
                                                      "when corresponding simulation option is set."));
    
        m_roughnessForm =
    
            new RoughnessForm(this, layer->roughnessSelection(), layer->expandRoughness, m_ec);
    
        m_layout->addRow(m_roughnessForm);
    
        m_roughness_row = m_layout->rowCount() - 1;
    
        for (auto* layout : layer->layoutItems())
    
            m_layout->addRow(new ParticleLayoutForm(this, layout, ec));
    
    
        // -- Button for adding a new layout
        auto* btn = new QPushButton("Add particle layout", this);
    
        connect(btn, &QPushButton::clicked, [this, ec] { ec->addLayoutItem(this); });
    
        m_structure_editing_widgets << btn;
    
        m_layout->addStructureEditingRow(btn);
    
        // listen to changes in materials to update the title (contains the material name). Necessary
        // to reflect e.g. a name change done in the material editor.
    
        connect(ec->materialModel(), &MaterialsSet::materialChanged, this, &LayerForm::updateTitle);
    
        updatePositionDependentElements();
    
    LayerItem* LayerForm::layerItem() const
    {
        return dynamic_cast<LayerItem*>(m_item);
    }
    
    
        QString material_text = "     Material: " + layerItem()->materialName();
        if (layerItem()->isAmbient())
            setTitle("Ambient" + material_text);
    
        else if (layerItem()->isSubstrate())
            setTitle("Substrate" + material_text);
    
        else {
            const SampleItem* sampleItem = m_ec->sampleItem();
            ASSERT(sampleItem);
            int i = Vec::indexOfPtr(layerItem(), sampleItem->uniqueLayerItems());
            setTitle("Layer " + QString::number(i) + material_text);
        }
    
    void LayerForm::updatePositionDependentElements()
    
        if (m_roughness_row == -1)
    
        const auto* sample = m_ec->sampleItem();
    
        const bool isAmbient = layerItem()->isAmbient();
        const bool isSubstrate = layerItem()->isSubstrate();
    
        const bool thicknessIsSemiInfinite =
    
            (isAmbient || isSubstrate) && (sample->uniqueLayerItems().size() > 1);
        const bool thicknessIsInfinite = isAmbient && (sample->uniqueLayerItems().size() == 1);
    
        m_roughnessForm->setVisible(!isAmbient);
    
        if (m_thickness_row == -1)
    
        m_roughnessForm->markLayerAsSubstrate(isSubstrate);
    
        QWidget* w = m_layout->itemAt(m_thickness_row, QFormLayout::FieldRole)->widget();
    
        if (thicknessIsSemiInfinite || thicknessIsInfinite) {
    
                m_layout->removeRow(m_thickness_row);
    
                info = new QLineEdit(this);
                info->setEnabled(false);
                info->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    
                m_layout->insertRow(m_thickness_row, layerItem()->thickness().label(), info);
    
            }
            info->setText(thicknessIsSemiInfinite ? "Semi-infinite" : "Infinite");
        } else if (!thicknessIsSemiInfinite && !thicknessIsInfinite
                   && (qobject_cast<QLineEdit*>(w) != nullptr)) {
    
            m_layout->removeRow(m_thickness_row);
    
            m_layout->insertValue(m_thickness_row, layerItem()->thickness());
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
        m_move_button->setVisible(m_ec->sampleItem()->uniqueLayerItems().size() > 1);
    
    void LayerForm::onLayoutAdded(ParticleLayoutItem* t)
    
        int index = Vec::indexOfPtr(t, layerItem()->layoutItems());
        const int rowInLayout = m_layout->rowCount() - layerItem()->layoutItems().size() + index;
    
        QWidget* w = new ParticleLayoutForm(this, t, m_ec);
    
        m_layout->insertRow(rowInLayout, w);
    
    void LayerForm::onAboutToRemoveLayout(ParticleLayoutItem* t)
    
        int index = Vec::indexOfPtr(t, layerItem()->layoutItems());
    
            m_layout->rowCount() - layerItem()->layoutItems().size() - 1 + index; // -1: btn
    
        m_layout->removeRow(rowInLayout);