// ************************************************************************************************ // // BornAgain: simulate and fit reflection and scattering // //! @file GUI/View/SampleDesigner/MesocrystalForm.cpp //! @brief Implements class MesocrystalForm //! //! @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/MesocrystalForm.h" #include "Base/Util/Assert.h" #include "GUI/Model/Sample/FormFactorItems.h" #include "GUI/Model/Sample/MesocrystalItem.h" #include "GUI/Model/Sample/ParticleItem.h" #include "GUI/Support/Util/ActionFactory.h" #include "GUI/View/SampleDesigner/HeinzFormLayout.h" #include <QAction> MesocrystalForm::MesocrystalForm(QWidget* parent, MesocrystalItem* mesocrystalItem, SampleEditorController* ec, bool allowRemove) : CollapsibleGroupBox("Mesocrystal", parent, mesocrystalItem->expandMesocrystal) , m_item(mesocrystalItem) , m_ec(ec) { m_layout = new HeinzFormLayout(ec); body()->setLayout(m_layout); m_layout->addVector(mesocrystalItem->position(), false); m_layout->addSelection(mesocrystalItem->rotationSelection()); m_layout->addValue(mesocrystalItem->abundance()); m_layout->addVector(mesocrystalItem->vectorA(), false); m_layout->addVector(mesocrystalItem->vectorB(), false); m_layout->addVector(mesocrystalItem->vectorC(), false); m_layout->addSelection(mesocrystalItem->outerShapeSelection()); m_basisCombo = createBasisCombo(this, mesocrystalItem->basisItem()); connect(m_basisCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MesocrystalForm::onBasisComboChanged); m_layout->addBoldRow("Basis type", m_basisCombo); m_rowOfBasisTypeCombo = m_layout->rowCount() - 1; createBasisWidgets(); //... top right corner actions // show in real space auto* showInRealspaceAction = ActionFactory::createShowInRealspaceAction(this, "meso crystal", [ec, mesocrystalItem] { ec->requestViewInRealspace(mesocrystalItem); }); addTitleAction(showInRealspaceAction); // duplicate m_duplicateAction = ActionFactory::createDuplicateAction(this, "meso crystal", [ec, mesocrystalItem] { ec->duplicateItemWithParticles(mesocrystalItem); }); addTitleAction(m_duplicateAction); // remove m_removeAction = ActionFactory::createRemoveAction( this, "meso crystal", [ec, mesocrystalItem] { ec->removeParticle(mesocrystalItem); }); if (allowRemove) addTitleAction(m_removeAction); } QComboBox* MesocrystalForm::createBasisCombo(QWidget* parent, ItemWithParticles* current) { auto* combo = new QComboBox(parent); WheelEventEater::install(combo); combo->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); uint32_t currentData = 0; for (auto type : FormFactorItemCatalog::types()) { const auto ui = FormFactorItemCatalog::uiInfo(type); combo->addItem(QIcon(ui.iconPath), ui.menuEntry, static_cast<uint32_t>(type)); if (auto* p = dynamic_cast<ParticleItem*>(current)) if (FormFactorItemCatalog::type(p->formFactorItem()) == type) currentData = static_cast<uint32_t>(type); } for (auto type : ItemWithParticlesCatalog::assemblyTypes()) { const auto ui = ItemWithParticlesCatalog::uiInfo(type); combo->addItem(QIcon(ui.iconPath), ui.menuEntry, 1000 + static_cast<uint32_t>(type)); if (ItemWithParticlesCatalog::type(current) == type) currentData = 1000 + static_cast<uint32_t>(type); } combo->setMaxVisibleItems(combo->count()); const auto currentIndex = combo->findData(currentData); ASSERT(currentIndex >= 0); combo->setCurrentIndex(currentIndex); return combo; } void MesocrystalForm::onBasisComboChanged() { while (m_layout->rowCount() > m_rowOfBasisTypeCombo + 1) m_layout->removeRow(m_rowOfBasisTypeCombo + 1); const auto currentData = m_basisCombo->currentData().toUInt(); if (currentData < 1000) m_ec->setMesocrystalBasis(this, static_cast<FormFactorItemCatalog::Type>(currentData)); else m_ec->setMesocrystalBasis(this, static_cast<ItemWithParticlesCatalog::Type>(currentData - 1000)); } void MesocrystalForm::createBasisWidgets() { if (!m_item->basisItem()) return; m_layout->addRow(LayerEditorUtil::createWidgetForItemWithParticles(this, m_item->basisItem(), false, m_ec, false)); } void MesocrystalForm::enableStructureEditing(bool b) { m_removeAction->setVisible(b); m_duplicateAction->setVisible(b); } MesocrystalItem* MesocrystalForm::mesocrystalItem() const { return m_item; }