Skip to content
Snippets Groups Projects
LayerEditorUtils.cpp 9.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • //  ************************************************************************************************
    //
    //  BornAgain: simulate and fit reflection and scattering
    //
    
    //! @file      GUI/View/SampleDesigner/LayerEditorUtils.cpp
    
    //! @brief     Implements class LayerEditorUtils
    //!
    //! @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/LayerEditorUtils.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "GUI/Model/Sample/CompoundItem.h"
    #include "GUI/Model/Sample/CoreAndShellItem.h"
    
    #include "GUI/Model/Sample/FormFactorItems.h"
    #include "GUI/Model/Sample/LayerRoughnessItems.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "GUI/Model/Sample/MesocrystalItem.h"
    
    #include "GUI/Model/Sample/ParticleItem.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "GUI/Model/Sample/ProfileItems.h"
    
    #include "GUI/View/Common/DoubleSpinBox.h"
    
    #include "GUI/View/SampleDesigner/CompoundForm.h"
    
    #include "GUI/View/SampleDesigner/CoreAndShellForm.h"
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
    #include "GUI/View/SampleDesigner/FormLayouter.h"
    #include "GUI/View/SampleDesigner/MesocrystalForm.h"
    
    #include "GUI/View/SampleDesigner/ParticleForm.h"
    
    
    #include <QLabel>
    #include <QMenu>
    #include <QPushButton>
    
    
    void updateLabelUnit(QLabel* label, const QString& unit)
    {
        QString text = label->text();
        const bool hasColon = text.indexOf(":") > 0;
        text = text.left(text.indexOf("["));
        text = text.trimmed();
        if (text.endsWith(":"))
            text.chop(1);
    
        if (!unit.isEmpty())
            text += " [" + unit + "]";
        if (hasColon)
            text += ":";
        label->setText(text);
    }
    
    } // namespace
    
    void LayerEditorUtils::updateLabelUnit(QLabel* label, DoubleSpinBox* editor)
    {
        ::updateLabelUnit(label, editor->displayUnitAsString());
    }
    
    void LayerEditorUtils::updateLabelUnit(QLabel* label)
    {
        if (auto* editor = dynamic_cast<DoubleSpinBox*>(label->buddy()))
            ::updateLabelUnit(label, editor->displayUnitAsString());
    }
    
    void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
    
                                                  const DoublePropertyRefs& valueDescriptors,
    
                                                  SampleEditorController* ec, bool vertically,
    
        const auto setNewValue = [ec](double newValue, DoubleProperty& d) {
    
            ec->setDouble(newValue, d);
        };
    
        addMultiPropertyToGrid(m_gridLayout, firstCol, valueDescriptors, setNewValue, vertically,
                               addSpacer);
    }
    
    void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
    
                                                  const DoublePropertyRefs& valueDescriptors,
    
                                                  function<void(double, DoubleProperty&)> setNewValue,
    
        for (DoubleProperty& d : valueDescriptors) {
    
    Ludwig Jaeck's avatar
    Ludwig Jaeck committed
            DoubleSpinBox* editor;
    
            if (d.label() == "Angle")
                editor = new DoubleSpinBox(d, false, 1, 1.0);
    
    Ludwig Jaeck's avatar
    Ludwig Jaeck committed
            else
    
                editor = new DoubleSpinBox(d);
    
            QObject::connect(editor, &DoubleSpinBox::baseValueChanged,
    
                             [setNewValue, &d](double newValue) { setNewValue(newValue, d); });
    
            QString labeltext = d.label();
    
            if (!vertically && !labeltext.endsWith(":"))
                labeltext += ":";
            auto* label = new QLabel(labeltext, m_gridLayout->parentWidget());
            label->setBuddy(editor); // necessary for unit-updating
            LayerEditorUtils::updateLabelUnit(label, editor);
    
            if (vertically) {
                m_gridLayout->addWidget(label, 0, col);
                m_gridLayout->addWidget(editor, 1, col);
                col++;
            } else {
                m_gridLayout->addWidget(label, 1, col++);
                m_gridLayout->addWidget(editor, 1, col++);
            }
        }
        if (addSpacer)
            m_gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding), 0, col);
    }
    
    void LayerEditorUtils::addMultiPropertyToGrid(QGridLayout* m_gridLayout, int firstCol,
    
                                                  const DoublePropertyRefs& valueDescriptors,
    
                                                  SampleEditorController* ec, bool addSpacer)
    
        addMultiPropertyToGrid(m_gridLayout, firstCol, valueDescriptors, ec,
    
                               valueDescriptors.size() > 1, addSpacer);
    }
    
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    void LayerEditorUtils::addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, VectorProperty& v,
                                           SampleEditorController* ec, bool vertically, bool addSpacer)
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
        addMultiPropertyToGrid(m_gridLayout, firstCol, {v.x(), v.y(), v.z()}, ec, vertically,
                               addSpacer);
    
    Mikhail Svechnikov's avatar
    Mikhail Svechnikov committed
    void LayerEditorUtils::addVectorToGrid(QGridLayout* m_gridLayout, int firstCol, VectorProperty& v,
    
                                           function<void(double, DoubleProperty&)> setNewValue,
    
        addMultiPropertyToGrid(m_gridLayout, firstCol, {v.x(), v.y(), v.z()}, setNewValue, vertically,
    
    QLabel* LayerEditorUtils::createBoldLabel(const QString& text)
    {
    
        auto* l = new QLabel(text);
    
        QFont f = l->font();
        f.setBold(true);
        l->setFont(f);
        return l;
    }
    
    
    DoublePropertyRefs LayerEditorUtils::doubleDescriptorsOfItem(RotationItem* item)
    
        return item->rotationValues();
    
    DoublePropertyRefs LayerEditorUtils::doubleDescriptorsOfItem(Profile2DItem* item)
    
    {
        return item->valueDescriptors();
    }
    
    
    DoublePropertyRefs LayerEditorUtils::doubleDescriptorsOfItem(Profile1DItem* item)
    
    DoublePropertyRefs LayerEditorUtils::doubleDescriptorsOfItem(FormFactorItem* item)
    
    DoublePropertyRefs LayerEditorUtils::doubleDescriptorsOfItem(LayerBasicRoughnessItem* r)
    
            return {r->sigma(), r->hurst(), r->lateralCorrelationLength()};
    
        return {};
    }
    
    QWidget* LayerEditorUtils::createWidgetForItemWithParticles(QWidget* parentWidget,
                                                                ItemWithParticles* itemWithParticles,
    
                                                                SampleEditorController* ec,
                                                                bool allowRemove /*= true*/)
    {
    
        if (auto* composition = dynamic_cast<CompoundItem*>(itemWithParticles))
            return new CompoundForm(parentWidget, composition, ec, allowRemove);
    
        if (auto* coreShell = dynamic_cast<CoreAndShellItem*>(itemWithParticles))
            return new CoreAndShellForm(parentWidget, coreShell, ec, allowRemove);
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
        if (auto* meso = dynamic_cast<MesocrystalItem*>(itemWithParticles))
            return new MesocrystalForm(parentWidget, meso, ec, allowRemove);
    
    
        if (auto* particle = dynamic_cast<ParticleItem*>(itemWithParticles))
    
            return new ParticleForm(parentWidget, particle, allowAbundance, ec, allowRemove);
    
    QPushButton* LayerEditorUtils::createAddParticleButton(
        QWidget* parentWidget, std::function<void(FormFactorItemCatalog::Type t)> slotAddFormFactor,
        std::function<void(ItemWithParticlesCatalog::Type t)> slotAddParticle)
    
    {
        auto* btn = new QPushButton("Add particle", parentWidget);
    
    
        auto* menu = new QMenu(btn);
    
        QMenu* menuForEntries = menu;
    
        const auto group = [&](const QString& title) { menuForEntries = menu->addMenu(title); };
    
    
        group("Hard particles");
        for (const auto type : FormFactorItemCatalog::hardParticleTypes()) {
            const auto ui = FormFactorItemCatalog::uiInfo(type);
    
            QAction* a = menuForEntries->addAction(QIcon(ui.iconPath), ui.menuEntry);
            a->setToolTip(ui.description);
    
            QObject::connect(a, &QAction::triggered, [=]() { slotAddFormFactor(type); });
        }
    
        for (const auto type : FormFactorItemCatalog::rippleTypes()) {
            const auto ui = FormFactorItemCatalog::uiInfo(type);
            QAction* a = menuForEntries->addAction(QIcon(ui.iconPath), ui.menuEntry);
            a->setToolTip(ui.description);
            QObject::connect(a, &QAction::triggered, [=]() { slotAddFormFactor(type); });
        }
    
        for (const auto type :
             {ItemWithParticlesCatalog::Type::Composition, ItemWithParticlesCatalog::Type::CoreShell,
    
    Wuttke, Joachim's avatar
    Wuttke, Joachim committed
              ItemWithParticlesCatalog::Type::Mesocrystal}) {
    
            const auto ui = ItemWithParticlesCatalog::uiInfo(type);
            QAction* a = menuForEntries->addAction(QIcon(ui.iconPath), ui.menuEntry);
            a->setToolTip(ui.description);
            QObject::connect(a, &QAction::triggered, [=]() { slotAddParticle(type); });
        }
    
    
        btn->setMenu(menu);
    
        return btn;
    }
    
    QList<QColor> LayerEditorUtils::predefinedLayerColors()
    {
        static QList<QColor> colors = {QColor(230, 255, 213), QColor(194, 252, 240),
                                       QColor(239, 228, 176), QColor(200, 191, 231),
                                       QColor(253, 205, 193), QColor(224, 193, 253)};
    
        return colors;
    }