Newer
Older
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/View/SampleDesigner/SampleForm.cpp
//!
//! @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/SampleForm.h"
#include "GUI/Model/Sample/SampleItem.h"
#include "GUI/View/Numeric/DoubleSpinBox.h"
#include "GUI/View/SampleDesigner/CompoundForm.h"
#include "GUI/View/SampleDesigner/CoreAndShellForm.h"
#include "GUI/View/SampleDesigner/HeinzFormLayout.h"
#include "GUI/View/SampleDesigner/LayerForm.h"
#include "GUI/View/SampleDesigner/MesocrystalForm.h"
#include "GUI/View/SampleDesigner/ParticleForm.h"
#include "GUI/View/SampleDesigner/ParticleLayoutForm.h"
#include "GUI/View/SampleDesigner/SampleEditorController.h"
#include "GUI/View/Widget/ApplicationSettings.h"
#include "GUI/View/Widget/GroupBoxes.h"
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QTextEdit>
namespace {
//! Widget with a button to add a layer (the "add layer" buttons shown between layers)
class AddLayerWidget : public QWidget {
public:
AddLayerWidget(QWidget* parent, LayerItem* layer, SampleEditorController* ec)
: QWidget(parent)
, m_layer(layer)
auto* btn = new QPushButton("Add layer", this);
l->addStretch();
l->addWidget(btn);
l->addStretch();

Wuttke, Joachim
committed
connect(btn, &QPushButton::clicked, [=]() { ec->addLayerItem(layer); });
}
LayerItem* m_layer;
};
} // namespace
SampleForm::SampleForm(SampleItem* sampleItem, SampleEditorController* ec)
: m_sampleItem(sampleItem)
{
setAttribute(Qt::WA_StyledBackground, true);
auto* summary = new CollapsibleGroupBox("Summary and layer-independent parameters", this,
sampleItem->expandInfo);
m_layout->addWidget(summary, 0, Qt::AlignTop);
auto* gLayout = new HeinzFormLayout(ec);
summary->body()->setLayout(gLayout);
nameEdit->setText(sampleItem->sampleName());
connect(nameEdit, &QLineEdit::textEdited, ec, &SampleEditorController::setSampleName);
gLayout->addBoldRow("Description:", descriptionEdit);
descriptionEdit->setFixedHeight(60);
descriptionEdit->setAcceptRichText(false);
descriptionEdit->setTabChangesFocus(true);
descriptionEdit->setPlainText(sampleItem->description());

Wuttke, Joachim
committed
connect(descriptionEdit, &QTextEdit::textChanged, [this, descriptionEdit]() {
m_ec->setSampleDescription(descriptionEdit->toPlainText());
});
gLayout->addValue(sampleItem->crossCorrLength());
// Processing external field is not implemented yet, so temporary disable it (see issue #654)
// m_layout->addVector(sampleItem->externalField(), false);
auto* showInRealspaceAction = ActionFactory::createShowInRealspaceAction(

Wuttke, Joachim
committed
this, "sample", [this] { m_ec->requestViewInRealspace(m_sampleItem); });
summary->addTitleAction(showInRealspaceAction);
for (auto* layer : sampleItem->layerItems()) {
m_layout->addWidget(new AddLayerWidget(this, layer, m_ec));
m_layout->addWidget(new LayerForm(this, layer, m_ec));
}
m_layout->addWidget(new AddLayerWidget(this, nullptr, m_ec));
m_layout->setSizeConstraint(QLayout::SetMinimumSize);
}
void SampleForm::onLayerAdded(LayerItem* layerItem)
const int rowInMultiLayer = m_sampleItem->layerItems().indexOf(layerItem);
const int rowInLayout = rowInMultiLayer * 2 + 1;
m_layout->insertWidget(rowInLayout, new LayerForm(this, layerItem, m_ec));
// same row => button is above!
m_layout->insertWidget(rowInLayout, new AddLayerWidget(this, layerItem, m_ec));
void SampleForm::onLayerMoved(LayerItem* layerItem)
{
LayerForm* wl = nullptr;
AddLayerWidget* al = nullptr;
for (int index = 0; index < m_layout->count(); index++) {
if (auto* w = dynamic_cast<AddLayerWidget*>(m_layout->itemAt(index)->widget()))
if (w->m_layer == layerItem) {
al = w;
m_layout->takeAt(index);
break;
}
}
for (int index = 0; index < m_layout->count(); index++) {
if (auto* w = dynamic_cast<LayerForm*>(m_layout->itemAt(index)->widget()))
if (w->layerItem() == layerItem) {
wl = w;
m_layout->takeAt(index);
break;
}
}
const int rowInMultiLayer = m_sampleItem->layerItems().indexOf(layerItem);
const int rowInLayout = rowInMultiLayer * 2 + 1;
// same row => button is above!
void SampleForm::onAboutToRemoveLayer(LayerItem* layerItem)
{
LayerForm* layerForm = nullptr;
AddLayerWidget* addLayerWidget = nullptr;
for (auto* c : findChildren<QWidget*>()) {
if (auto* w = dynamic_cast<AddLayerWidget*>(c))
if (w->m_layer == layerItem)
addLayerWidget = w;
if (auto* w = dynamic_cast<LayerForm*>(c)) {
if (w->layerItem() == layerItem)
layerForm = w;
}
}
if (layerForm) {
// delete editors which are subscribed to SessionItems
GUI::Util::Layout::clearLayout(layerForm->layout());
layerForm->hide();
layerForm->setParent(nullptr); // so it is not findable in update routines
layerForm->deleteLater(); // delete later (this is the sender)
}
LayerForm* SampleForm::findNextLayerForm(QWidget* w)
{
while (w != nullptr && dynamic_cast<LayerForm*>(w) == nullptr) {
if (index + 1 < m_layout->count())
w = m_layout->itemAt(index + 1)->widget();
}
return dynamic_cast<LayerForm*>(w);
}