1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/View/Sample/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/Sample/InterferenceForm.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include "GUI/Model/Sample/InterferenceItems.h"
#include "GUI/Model/Sample/Lattice2DItems.h"
#include "GUI/Model/Sample/ParticleLayoutItem.h"
#include "GUI/View/Base/CustomEventFilters.h"
#include "GUI/View/Numeric/NumWidgetUtil.h"
#include "GUI/View/Sample/HeinzFormLayout.h"
#include "GUI/View/Sample/LatticeTypeSelectionForm.h"
InterferenceForm::InterferenceForm(QWidget* parent, ParticleLayoutItem* layoutItem,
SampleEditorController* ec)
: CollapsibleGroupBox("Interference Function", parent, layoutItem->expandInterference)
, m_cb(new QComboBox(this))
, m_layout_item(layoutItem)
, m_ec(ec)
{
m_layout = new HeinzFormLayout(m_ec);
body()->setLayout(m_layout);
WheelEventEater::install(m_cb);
const auto& d = layoutItem->interferenceSelection();
m_cb->addItems(d.menuEntries());
m_cb->setCurrentIndex(d.certainIndex());
m_cb->setMaxVisibleItems(m_cb->count());
m_cb->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_layout->addBoldRow("Type:", m_cb);
createInterferenceWidgets();
updateTitle();
connect(m_cb, &QComboBox::currentIndexChanged,
[this](int newIndex) { m_ec->selectInterference(this, newIndex); });
}
void InterferenceForm::onInterferenceTypeChanged()
{
while (m_layout->rowCount() > 1)
m_layout->removeRow(1);
createInterferenceWidgets();
updateTitle();
}
void InterferenceForm::createInterferenceWidgets()
{
auto* interference = m_layout_item->interferenceSelection().certainItem();
// 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 = [this, interference](DoubleProperty& d) {
m_layout->addValue(
d, [this, interference](double) { m_ec->setDensityRelatedValue(interference); });
};
if (auto* itf = dynamic_cast<Interference1DLatticeItem*>(interference)) {
m_layout->addValue(itf->positionVariance());
m_layout->addValue(itf->length());
m_layout->addValue(itf->rotationAngle());
m_layout->addSelection(itf->decayFunctionSelection());
} else if (auto* itf = dynamic_cast<InterferenceRadialParacrystalItem*>(interference)) {
m_layout->addValue(itf->positionVariance());
m_layout->addValue(itf->peakDistance());
m_layout->addValue(itf->dampingLength());
m_layout->addValue(itf->domainSize());
m_layout->addValue(itf->kappa());
m_layout->addSelection(itf->probabilityDistributionSelection());
} else if (auto* itf = dynamic_cast<InterferenceHardDiskItem*>(interference)) {
m_layout->addValue(itf->positionVariance());
m_layout->addValue(itf->radius());
addDensityRelatedValue(itf->density());
} else if (auto* itf = dynamic_cast<Interference2DLatticeItem*>(interference)) {
m_layout->addValue(itf->positionVariance());
auto* w = new LatticeTypeSelectionForm(this, itf, m_ec);
m_layout->addBoldRow(itf->latticeTypeSelection().piLabel(), w);
m_layout->addSelection(itf->decayFunctionSelection());
} else if (auto* itf = dynamic_cast<InterferenceFinite2DLatticeItem*>(interference)) {
m_layout->addValue(itf->positionVariance());
m_layout->addBoldRow("Domain size 1:",
GUI::Util::createIntSpinBox([itf] { return itf->domainSize1(); },
[itf](int v) {
itf->setDomainSize1(v);
emit gDoc->sampleChanged();
},
RealLimits::lowerLimited(1),
"Domain size 1 in number of unit cells"));
m_layout->addBoldRow("Domain size 2:",
GUI::Util::createIntSpinBox([itf] { return itf->domainSize2(); },
[itf](int v) {
itf->setDomainSize2(v);
emit gDoc->sampleChanged();
},
RealLimits::lowerLimited(1),
"Domain size 2 in number of unit cells"));
auto* w = new LatticeTypeSelectionForm(this, itf, m_ec);
m_layout->addBoldRow(itf->latticeTypeSelection().piLabel(), w);
} else if (auto* itf = dynamic_cast<Interference2DParacrystalItem*>(interference)) {
m_layout->addValue(itf->positionVariance());
m_layout->addValue(itf->dampingLength());
m_layout->addValue(itf->domainSize1());
m_layout->addValue(itf->domainSize2());
auto* w = new LatticeTypeSelectionForm(this, itf, m_ec);
m_layout->addBoldRow(itf->latticeTypeSelection().piLabel(), w);
m_layout->addSelection(itf->probabilityDistributionSelection1());
m_layout->addSelection(itf->probabilityDistributionSelection2());
}
}
void InterferenceForm::updateTitle()
{
setTitle("Interference Function (" + m_cb->currentText() + ")");
}
|