Newer
Older
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/View/Sample/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/Sample/SampleForm.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include "GUI/Model/Sample/LayerItem.h"
#include "GUI/Model/Sample/LayerStackItem.h"
#include "GUI/Model/Sample/SamplesSet.h"
#include "GUI/View/Base/ActionFactory.h"
#include "GUI/View/Base/LayoutUtil.h"
#include "GUI/View/Sample/CompoundForm.h"
#include "GUI/View/Sample/CoreAndShellForm.h"
#include "GUI/View/Sample/HeinzFormLayout.h"
#include "GUI/View/Sample/LayerForm.h"
#include "GUI/View/Sample/LayerStackForm.h"
#include "GUI/View/Sample/MesocrystalForm.h"
#include "GUI/View/Sample/ParticleForm.h"
#include "GUI/View/Sample/ParticleLayoutForm.h"
#include "GUI/View/Sample/SampleEditorController.h"
#include "GUI/View/Widget/AppConfig.h"
#include <QLabel>
#include <QLineEdit>
#include <QTextEdit>
namespace {
//! Widget with a button to add a layer or stack (the "Add layer/add stack" buttons shown between
//! items)
class AddLayerContainerWidget : public QWidget {
AddLayerContainerWidget(QWidget* parent, LayerStackItem& parentStackItem,
ItemWithLayers* itemBefore, SampleEditorController* ec)
, m_item(itemBefore)
l->addStretch();
connect(layer_btn, &QPushButton::clicked,
[&] { ec->addLayerItem(parentStackItem, itemBefore); });
auto* stack_btn = new QPushButton("Add stack", this);
l->addWidget(stack_btn);
connect(stack_btn, &QPushButton::clicked,
[&] { ec->addLayerItem(parentStackItem, itemBefore); });
ItemWithLayers* m_item;
};
} // namespace
SampleForm::SampleForm(SampleItem* sampleItem, SampleEditorController* ec)
: m_layout(new QVBoxLayout(this))
{
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->name());
connect(nameEdit, &QLineEdit::textEdited,
[](const QString& s) { gDoc->samplesRW()->setCurrentName(s); });
gLayout->addBoldRow("Description:", descriptionEdit);
descriptionEdit->setFixedHeight(60);
descriptionEdit->setAcceptRichText(false);
descriptionEdit->setTabChangesFocus(true);
descriptionEdit->setPlainText(sampleItem->description());
connect(descriptionEdit, &QTextEdit::textChanged, [descriptionEdit] {
gDoc->samplesRW()->setCurrentDescription(descriptionEdit->toPlainText());

Wuttke, Joachim
committed
});
// Processing external field is not implemented yet, so temporary disable it (see issue #654)
// m_layout->addVector(sampleItem->externalField(), false);
auto* showInRealspaceAction = ActionFactory::createShowInRealspaceAction(
this, "sample", [this] { m_ec->requestViewInRealspace(m_sample_item); });
summary->addTitleAction(showInRealspaceAction);
for (auto* item : sampleItem->componentItems()) {
m_layout->addWidget(
new AddLayerContainerWidget(this, m_sample_item->outerStackItem(), item, m_ec), 0,
Qt::AlignTop);
if (auto* layer = dynamic_cast<LayerItem*>(item))
m_layout->addWidget(new LayerForm(this, layer, m_ec), 0, Qt::AlignTop);
else if (auto* stack = dynamic_cast<LayerStackItem*>(item))
m_layout->addWidget(new LayerStackForm(this, stack, m_ec), 0, Qt::AlignTop);
else
ASSERT_NEVER;
m_layout->addWidget(
new AddLayerContainerWidget(this, m_sample_item->outerStackItem(), nullptr, m_ec), 0,
Qt::AlignTop);
m_layout->setSizeConstraint(QLayout::SetMinimumSize);
}
void SampleForm::onLayerAdded(LayerItem* layerItem)
const int rowInMultiLayer = Vec::indexOfPtr(layerItem, m_sample_item->uniqueLayerItems());
const int rowInLayout = rowInMultiLayer * 2 + 1;
m_layout->insertWidget(rowInLayout, new LayerForm(this, layerItem, m_ec), 0, Qt::AlignTop);
// same row => button is above!
m_layout->insertWidget(
rowInLayout,
new AddLayerContainerWidget(this, m_sample_item->outerStackItem(), layerItem, m_ec), 0,
Qt::AlignTop);
void SampleForm::onLayerMoved(ItemWithLayers* item)
LayerContainerForm* wl = nullptr;
AddLayerContainerWidget* al = nullptr;
for (int index = 0; index < m_layout->count(); index++) {
if (auto* w = dynamic_cast<AddLayerContainerWidget*>(m_layout->itemAt(index)->widget()))
if (w->m_item == item) {
al = w;
m_layout->takeAt(index);
break;
}
}
for (int index = 0; index < m_layout->count(); index++) {
if (auto* w = dynamic_cast<LayerContainerForm*>(m_layout->itemAt(index)->widget()))
if (w->item() == item) {
wl = w;
m_layout->takeAt(index);
break;
}
}
const int rowInMultiLayer = Vec::indexOfPtr(item, m_sample_item->uniqueLayerItems());
const int rowInLayout = rowInMultiLayer * 2 + 1;
m_layout->insertWidget(rowInLayout, wl, 0, Qt::AlignTop);
// same row => button is above!
m_layout->insertWidget(rowInLayout, al, 0, Qt::AlignTop);
void SampleForm::onAboutToRemoveLayerContainer(ItemWithLayers* itemWithLayers)
LayerContainerForm* layerContainerForm = nullptr;
AddLayerContainerWidget* addLayerWidget = nullptr;
for (auto* c : findChildren<QWidget*>()) {
if (auto* w = dynamic_cast<AddLayerContainerWidget*>(c))
if (w->m_item == itemWithLayers)
addLayerWidget = w;
if (auto* w = dynamic_cast<LayerContainerForm*>(c)) {
if (w->item() == itemWithLayers)
layerContainerForm = w;
}
}
if (layerContainerForm) {
// delete editors which are subscribed to SessionItems
GUI::Util::Layout::clearLayout(layerContainerForm->layout());
layerContainerForm->hide();
layerContainerForm->setParent(nullptr); // so it is not findable in update routines
layerContainerForm->deleteLater(); // delete later (this is the sender)
void SampleForm::updateRowVisibilities()
{
c->updateLayerPositionDependentElements();
}
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);
}