Newer
Older
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/View/SampleDesigner/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/SampleDesigner/LayerForm.h"
#include "GUI/Model/Sample/LayerItem.h"
#include "GUI/Model/Sample/MultiLayerItem.h"
#include "GUI/Model/Types/UIntDescriptor.h"
#include "GUI/View/SampleDesigner/ActionFactory.h"
#include "GUI/View/SampleDesigner/MaterialInplaceForm.h"
#include "GUI/View/SampleDesigner/ParticleLayoutForm.h"
#include "GUI/View/SampleDesigner/WidgetMoverButton.h"
#include "GUI/View/Tool/GroupBoxCollapser.h"
#include <QLineEdit>
#include <QMenu>
#include <QPushButton>
LayerForm::LayerForm(QWidget* parent, LayerItem* layer, SampleEditorController* ec)
: QGroupBox(parent), m_layer(layer), m_ec(ec)
{
setTitle(m_layer->itemName());
m_layouter.reset(new FormLayouter(this, ec));
m_layouter->setContentsMargins(6, 6, 0, 6);
m_collapser = GroupBoxCollapser::installIntoGroupBox(this, false);
m_removeAction =
ActionFactory::createRemoveAction(this, "layer", [=] { ec->removeLayer(layer); });
auto* chooseColorAction = new QAction(this);
chooseColorAction->setText("Choose color");
chooseColorAction->setIcon(QIcon(":/images/palette.svg"));
chooseColorAction->setIconText("Choose color");
chooseColorAction->setToolTip("Choose a color for this layer");
auto* menu = new QMenu(this);
chooseColorAction->setMenu(menu);
for (auto col : LayerEditorUtils::predefinedLayerColors()) {
QPixmap p(64, 64);
p.fill(col);
auto ca = menu->addAction(QIcon(p), "");
connect(ca, &QAction::triggered, [=]() {
layer->setColor(col);
updateColor();
});
}
auto* moveButton = new WidgetMoverButton(this, this, 1);
moveButton->setToolTip("Move layer up/down");
connect(moveButton, &WidgetMoverButton::startingToMove, ec,
&SampleEditorController::onStartingToMoveLayer);
connect(moveButton, &WidgetMoverButton::finishedMoving, ec,
&SampleEditorController::onStoppedToMoveLayer);
auto* showInRealSpaceAction = ActionFactory::createShowInRealSpaceAction(
this, "layer", [=] { m_ec->requestViewInRealSpace(layer); });
m_collapser->addAction(showInRealSpaceAction);
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
m_collapser->addAction(chooseColorAction);
m_collapser->addAction(m_removeAction);
m_collapser->addWidget(moveButton);
m_structureEditingWidgets << moveButton;
QColor bckgroundCol = m_layer->color();
setStyleSheet("QGroupBox {background-color: " + bckgroundCol.name(QColor::HexRgb) + "}");
m_layouter->addRow("Material:", new MaterialInplaceForm(this, layer, ec));
m_thicknessRow = m_layouter->addValue(m_layer->thickness());
m_layouter->addValue(m_layer->numSlices());
m_roughnessRow = m_layouter->addSelection(m_layer->roughness());
// -- layouts
for (auto layout : layer->layouts())
m_layouter->addRow(new ParticleLayoutForm(this, layout, ec));
// -- Button for adding a new layout
auto* btn = new QPushButton("Add particle layout", this);
connect(btn, &QPushButton::clicked, [=] { ec->addLayout(this); });
m_structureEditingWidgets << btn;
m_layouter->addStructureEditingRow(btn);
updateLayerPositionDependentElements();
}
void LayerForm::enableStructureEditing(bool b)
{
m_removeAction->setVisible(b);
for (auto w : m_structureEditingWidgets)
w->setVisible(b);
}
void LayerForm::updateColor()
{
QColor bckgroundCol = m_layer->color();
setStyleSheet("QGroupBox {background-color: " + bckgroundCol.name(QColor::HexRgb) + "}");
}
void LayerForm::updateTitle()
{
const auto* multiLayer = dynamic_cast<MultiLayerItem*>(m_layer->parent());
int i = multiLayer->layers().indexOf(m_layer);
m_collapser->setTitle("Layer " + QString::number(i)
+ " Material: " + m_layer->materialName());
}
void LayerForm::updateLayerPositionDependentElements()
{
if (m_roughnessRow == -1)
return;
updateTitle();
const auto* multiLayer = dynamic_cast<MultiLayerItem*>(m_layer->parent());
const bool isFirstLayer = multiLayer->layers().first() == m_layer;
const bool isLastLayer = multiLayer->layers().last() == m_layer;
const bool thicknessIsSemiInfinite =
(isFirstLayer || isLastLayer) && (multiLayer->layers().size() != 1);
const bool thicknessIsInfinite = multiLayer->layers().size() == 1;
m_layouter->setRowVisible(m_roughnessRow, !isFirstLayer);
if (m_thicknessRow == -1)
return;
QWidget* w = m_layouter->layout()->itemAt(m_thicknessRow, QFormLayout::FieldRole)->widget();
if (thicknessIsSemiInfinite || thicknessIsInfinite) {
QLineEdit* info = qobject_cast<QLineEdit*>(w);
if (info == nullptr) {
m_layouter->removeRow(m_thicknessRow);
info = new QLineEdit(this);
info->setEnabled(false);
info->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_layouter->insertRow(m_thicknessRow, m_layer->thickness().label, info);
}
info->setText(thicknessIsSemiInfinite ? "Semi-infinite" : "Infinite");
} else if (!thicknessIsSemiInfinite && !thicknessIsInfinite
&& (qobject_cast<QLineEdit*>(w) != nullptr)) {
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
m_layouter->removeRow(m_thicknessRow);
m_layouter->insertValue(m_thicknessRow, m_layer->thickness());
}
}
void LayerForm::onLayoutAdded(ParticleLayoutItem* newLayoutItem)
{
int index = m_layer->layouts().indexOf(newLayoutItem);
const int rowInLayout = m_layouter->layout()->rowCount() - m_layer->layouts().size() + index;
m_layouter->insertRow(rowInLayout, new ParticleLayoutForm(this, newLayoutItem, m_ec));
}
void LayerForm::onAboutToRemoveLayout(ParticleLayoutItem* layoutItem)
{
int index = m_layer->layouts().indexOf(layoutItem);
const int rowInLayout =
m_layouter->layout()->rowCount() - m_layer->layouts().size() - 1 + index; // -1: btn
m_layouter->removeRow(rowInLayout);
}
LayerItem* LayerForm::layerItem() const
{
return m_layer;
}