-
Matthias Puchner authoredMatthias Puchner authored
LayerItem.cpp 5.24 KiB
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/Model/Sample/LayerItem.cpp
//! @brief Implements class LayerItem
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
// ************************************************************************************************
#include "GUI/Model/Sample/LayerItem.h"
#include "GUI/Model/Group/GroupInfo.h"
#include "GUI/Model/Sample/LayerRoughnessItems.h"
#include "GUI/Model/Sample/MesoCrystalItem.h"
#include "GUI/Model/Sample/MultiLayerItem.h"
#include "GUI/Model/Sample/ParticleCompositionItem.h"
#include "GUI/Model/Sample/ParticleCoreShellItem.h"
#include "GUI/Model/Sample/ParticleItem.h"
#include "GUI/Model/Sample/ParticleLayoutItem.h"
#include "GUI/Model/Types/DoubleDescriptor.h"
#include "GUI/Model/Types/UIntDescriptor.h"
#include "GUI/Util/Error.h"
#include <QColor>
namespace {
QVector<ItemWithMaterial*> layoutItemsWithMaterial(ParticleLayoutItem* item)
{
QVector<ItemWithMaterial*> result;
QVector<ItemWithParticles*> itemsWithParticles{item->particles()};
while (!itemsWithParticles.empty()) {
auto* item = itemsWithParticles.takeFirst();
if (!item)
continue;
if (auto* p = dynamic_cast<ParticleCompositionItem*>(item))
itemsWithParticles << p->particles();
else if (auto* p = dynamic_cast<MesoCrystalItem*>(item))
itemsWithParticles << p->basisParticle();
else if (auto* p = dynamic_cast<ParticleItem*>(item))
result << p;
else if (auto* p = dynamic_cast<ParticleCoreShellItem*>(item)) {
if (p->core())
result << p->core();
if (p->shell())
result << p->shell();
} else
ASSERT(false);
}
return result;
}
} // namespace
LayerItem::LayerItem() : SessionItem(M_TYPE), ItemWithMaterial(M_TYPE)
{
addProperty(P_THICKNESS, 0.0)->setLimits(RealLimits::lowerLimited(0.0));
addProperty(P_NSLICES, 1)->setLimits(RealLimits::lowerLimited(0.0));
addProperty(P_COLOR, QColor()); // initially no color
GroupInfo info;
info.add(LayerBasicRoughnessItem::M_TYPE, "Basic");
info.add(LayerZeroRoughnessItem::M_TYPE, "No");
info.setDefaultType(LayerZeroRoughnessItem::M_TYPE);
addGroupProperty(P_ROUGHNESS, info)->setToolTip("Roughness of top interface");
registerTag(T_LAYOUTS, 0, -1, {ParticleLayoutItem::M_TYPE});
setDefaultTag(T_LAYOUTS);
}
QString LayerItem::layerName() const
{
return itemName();
}
QVector<ItemWithMaterial*> LayerItem::itemsWithMaterial()
{
QVector<ItemWithMaterial*> result;
result.push_back(this);
for (auto* layout : layouts())
result.append(layoutItemsWithMaterial(layout));
return result;
}
QVector<ItemWithParticles*> LayerItem::itemsWithParticles() const
{
QVector<ItemWithParticles*> result;
for (auto* layout : layouts())
result << layout->containedItemsWithParticles();
return result;
}
DoubleDescriptor LayerItem::thickness() const
{
DoubleDescriptor d(getItem(P_THICKNESS), Unit::nanometer);
d.tooltip = "Thickness of the layer";
return d;
}
bool LayerItem::isThicknessPropertyName(const QString& name)
{
return name == P_THICKNESS;
}
void LayerItem::setThicknessEnabled(bool enabled)
{
getItem(P_THICKNESS)->setEnabled(enabled);
}
SelectionDescriptor<std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*>>
LayerItem::roughness()
{
SelectionDescriptor<std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*>> d(
item<GroupItem>(P_ROUGHNESS));
d.currentItem = [=]() -> std::variant<LayerZeroRoughnessItem*, LayerBasicRoughnessItem*> {
if (auto* r = dynamic_cast<LayerBasicRoughnessItem*>(getGroupItem(P_ROUGHNESS)))
return {r};
return {dynamic_cast<LayerZeroRoughnessItem*>(getGroupItem(P_ROUGHNESS))};
};
return d;
}
void LayerItem::setRoughnessEnabled(bool enabled)
{
getItem(P_ROUGHNESS)->setEnabled(enabled);
}
UIntDescriptor LayerItem::numSlices() const
{
UIntDescriptor d(getItem(P_NSLICES), Unit::unitless);
d.tooltip = "Number of horizontal slices.\n"
"Used for Average Layer Material calculations \n"
"when corresponding simulation option is set.";
return d;
}
QVector<ParticleLayoutItem*> LayerItem::layouts() const
{
return items<ParticleLayoutItem>(T_LAYOUTS);
}
ParticleLayoutItem* LayerItem::addLayout()
{
return model()->insertItem<ParticleLayoutItem>(this);
}
void LayerItem::removeLayout(ParticleLayoutItem* layout)
{
model()->removeItem(layout);
}
QColor LayerItem::color() const
{
return getItemValue(P_COLOR).value<QColor>();
}
void LayerItem::setColor(const QColor& color)
{
setItemValue(P_COLOR, color);
}
void LayerItem::setIsTopLayer(bool b)
{
m_isTopLayer = b;
}
bool LayerItem::isTopLayer() const
{
return m_isTopLayer;
}
void LayerItem::setIsBottomLayer(bool b)
{
m_isBottomLayer = b;
}
bool LayerItem::isBottomLayer() const
{
return m_isBottomLayer;
}