Newer
Older
// ************************************************************************************************
//
// BornAgain: simulate and fit reflection and scattering
//
//! @file GUI/View/SampleDesigner/LayerOrientedSampleEditor.cpp
//! @brief Implements class LayerOrientedSampleEditor
//!
//! @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/LayerOrientedSampleEditor.h"
Matthias Puchner
committed
#include "GUI/Application/ApplicationSettings.h"
#include "GUI/Model/Sample/SampleItem.h"
#include "GUI/View/SampleDesigner/LayerEditorUtil.h"
#include "GUI/View/SampleDesigner/SampleEditorController.h"
#include <QBoxLayout>
Matthias Puchner
committed
#include <QPushButton>
LayerOrientedSampleEditor::LayerOrientedSampleEditor(QWidget* parent, ProjectDocument* document)
: QWidget(parent)
, m_undoAction(nullptr)
, m_redoAction(nullptr)
, m_showInlineEditButtonsAction(nullptr)
, m_asAngstromAction(nullptr)
, m_document(document)
{
m_scrollArea = new QScrollArea(this);
m_scrollArea->setWidgetResizable(true);
m_scrollArea->setWidget(createEmptyWidget());
m_toolbar = new StyledToolbar(this);
m_toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
auto* mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
mainLayout->addWidget(m_toolbar);
mainLayout->addWidget(m_scrollArea);
m_showInlineEditButtonsAction = new QAction(QIcon(":/images/edit.svg"), "Edit structure", this);
connect(m_showInlineEditButtonsAction, &QAction::toggled, this,
&LayerOrientedSampleEditor::onShowInlineEditButtonsToggled);
m_showInlineEditButtonsAction->setCheckable(true);
m_showInlineEditButtonsAction->setChecked(true);
m_toolbar->addAction(m_showInlineEditButtonsAction);
m_asAngstromAction = new QAction(this);
m_asAngstromAction->setIcon(QIcon(":/images/unit_angstrom.svg"));
m_asAngstromAction->setToolTip(u8"Use \u00c5ngstrom as unit (where applicable)");
connect(m_asAngstromAction, &QAction::toggled, this,
&LayerOrientedSampleEditor::onUnitActionToggled);
m_asAngstromAction->setCheckable(true);
auto* asNanometerAction = new QAction(this);
asNanometerAction->setIcon(QIcon(":/images/unit_nm.svg"));
asNanometerAction->setToolTip("Use nanometer as unit (where applicable)");
connect(asNanometerAction, &QAction::toggled, this,
&LayerOrientedSampleEditor::onUnitActionToggled);
asNanometerAction->setCheckable(true);
auto* ag = new QActionGroup(this);
ag->addAction(asNanometerAction);
ag->addAction(m_asAngstromAction);
if (appSettings->defaultUnitIsAngstrom())
m_asAngstromAction->setChecked(true);
else
asNanometerAction->setChecked(true);
m_toolbar->addActions(ag->actions());
}
LayerOrientedSampleEditor::~LayerOrientedSampleEditor()
{
qDeleteAll(m_editControllers.values());
}
void LayerOrientedSampleEditor::setCurrentSample(SampleItem* sampleItem)
m_editControllers[m_currentSample]->setSampleForm(nullptr);
delete m_scrollArea->takeWidget();
// use the correct toolbar buttons (from correct undo stack)
delete m_undoAction;
m_undoAction = nullptr;
delete m_redoAction;
m_redoAction = nullptr;
m_currentSample = sampleItem;
if (m_currentSample == nullptr) {
m_scrollArea->setWidget(createEmptyWidget());
updateActionEnabling();
return;
}
if (!m_editControllers.contains(m_currentSample))
m_editControllers.insert(m_currentSample,
new SampleEditorController(m_document, m_currentSample));
auto* ec = m_editControllers[m_currentSample];
connect(ec, &SampleEditorController::requestViewInRealspace, this,
&LayerOrientedSampleEditor::requestViewInRealspace);
connect(ec, &SampleEditorController::aboutToRemoveItem, this,
&LayerOrientedSampleEditor::aboutToRemoveItem);
connect(ec, &SampleEditorController::modified, this, &LayerOrientedSampleEditor::modified);
m_undoAction = ec->undoStack()->createUndoAction(this);
m_redoAction = ec->undoStack()->createRedoAction(this);
m_undoAction->setIcon(QIcon(":/images/undo-variant.svg"));
m_redoAction->setIcon(QIcon(":/images/redo.svg"));
m_toolbar->addAction(m_undoAction);
m_toolbar->addAction(m_redoAction);
createLayerColors();
m_currentSampleWidget = new SampleForm(this, m_currentSample, ec);
ec->setSampleForm(m_currentSampleWidget);
m_currentSampleWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_scrollArea->setWidget(m_currentSampleWidget);
m_currentSampleWidget->showInlineEditButtons(m_showInlineEditButtonsAction->isChecked());
m_currentSampleWidget->setUseAngstrom(m_asAngstromAction->isChecked());
updateActionEnabling();
}
void LayerOrientedSampleEditor::updateActionEnabling()
{
Matthias Puchner
committed
// Undo/Redo is not complete => hide the related buttons/actions
if (m_undoAction)
m_undoAction->setVisible(false);
if (m_redoAction)
m_redoAction->setVisible(false);
}
void LayerOrientedSampleEditor::onShowInlineEditButtonsToggled(bool checked)
{
if (m_currentSampleWidget)
m_currentSampleWidget->showInlineEditButtons(checked);
void LayerOrientedSampleEditor::onUnitActionToggled()
if (m_currentSampleWidget)
m_currentSampleWidget->setUseAngstrom(m_asAngstromAction->isChecked());
}
void LayerOrientedSampleEditor::createLayerColors() // #baLayerEditor move to better place
{
return;
int col = 0;
for (auto* l : m_currentSample->layerItems()) {
if (l->color().isValid())
continue;
l->setColor(LayerEditorUtils::predefinedLayerColors()[col]);
col++;
if (col == LayerEditorUtils::predefinedLayerColors().size())
col = 0;
}
}
QWidget* LayerOrientedSampleEditor::createEmptyWidget()
{
auto* emptyWidget = new QWidget(this);
Matthias Puchner
committed
auto* btn = new QPushButton("Create sample", emptyWidget);
connect(btn, &QPushButton::clicked, this, &LayerOrientedSampleEditor::requestCreateNewSample);
auto* layout = new QHBoxLayout(emptyWidget);
layout->setContentsMargins(10, 20, 10, 20);
layout->addStretch();
layout->addWidget(btn);
layout->addStretch();
layout->setAlignment(Qt::AlignTop);
return emptyWidget;
}