Newer
Older
// ************************************************************************************************
// BornAgain: simulate and fit reflection and scattering
//! @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/Project/ProjectDocument.h"
#include "GUI/Model/Sample/ItemWithParticles.h"
#include "GUI/Model/Sample/LayerItem.h"
#include "GUI/Model/Sample/MultiLayerItem.h"
#include "GUI/Model/Sample/ParticleLayoutItem.h"
Matthias Puchner
committed
#include "GUI/Model/Sample/SampleModel.h"
#include "GUI/View/Common/StyledToolBar.h"
Matthias Puchner
committed
#include "GUI/View/Realspace/RealSpaceCanvas.h"
#include "GUI/View/SampleDesigner/LayerOrientedSampleEditor.h"
#include "GUI/View/SampleDesigner/RealSpacePanel.h"
#include "GUI/View/SampleDesigner/SampleListView.h"
#include "GUI/View/SampleDesigner/ScriptPanel.h"
#include <QBoxLayout>
#include <QToolButton>
SampleView::SampleView(QWidget* parent, ProjectDocument* document)
: QMainWindow(parent), m_document(document)
Matthias Puchner
committed
Matthias Puchner
committed
connect(m_document, &ProjectDocument::singleSampleModeChanged, this,
&SampleView::updateSingleSampleMode);
m_docks = new DocksController(this);
auto* editor = new LayerOrientedSampleEditor(this, document);
auto* sampleSelectionPane = new QWidget(this);
auto* sampleSelectionLayout = new QVBoxLayout(sampleSelectionPane);
sampleSelectionLayout->setContentsMargins(0, 0, 0, 0);
sampleSelectionLayout->setSpacing(0);
auto* sampleSelectionToolbar = new StyledToolBar(sampleSelectionPane);
auto* sampleSelectionView = new SampleListView(this, m_document);
sampleSelectionToolbar->addAction(sampleSelectionView->newSampleAction());
#ifdef BORNAGAIN_PYTHON
sampleSelectionToolbar->addAction(sampleSelectionView->importSampleAction());
#endif
sampleSelectionToolbar->addAction(sampleSelectionView->chooseFromLibraryAction());
if (auto* btn = dynamic_cast<QToolButton*>(sampleSelectionToolbar->widgetForAction(
sampleSelectionView->chooseFromLibraryAction())))
btn->setPopupMode(QToolButton::InstantPopup);
sampleSelectionToolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
sampleSelectionLayout->addWidget(sampleSelectionToolbar);
sampleSelectionLayout->addWidget(sampleSelectionView);
sampleSelectionView->setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
auto* scriptPanel = new ScriptPanel(m_document->sampleModel(), this);
Matthias Puchner
committed
m_realSpacePanel = new RealSpacePanel(m_document->materialModel(), this);
sampleSelectionPane->setWindowTitle("Samples");
m_docks->addWidget(SAMPLE_LIST, sampleSelectionPane, Qt::LeftDockWidgetArea);
Matthias Puchner
committed
m_docks->addWidget(REALSPACEPANEL, m_realSpacePanel, Qt::BottomDockWidgetArea);
m_docks->addWidget(PYTHONPANEL, scriptPanel, Qt::BottomDockWidgetArea);
connect(sampleSelectionView, &SampleListView::currentSampleChanged, editor,
&LayerOrientedSampleEditor::setCurrentSample);
connect(sampleSelectionView, &SampleListView::currentSampleChanged, m_realSpacePanel->canvas(),
&RealSpaceCanvas::setCurrentItem);
connect(sampleSelectionView, &SampleListView::currentSampleChanged, scriptPanel,
&ScriptPanel::setCurrentSample);
connect(editor, &LayerOrientedSampleEditor::modified, scriptPanel,
&ScriptPanel::onSampleModified);
Matthias Puchner
committed
connect(editor, &LayerOrientedSampleEditor::requestViewInRealSpace, this,
&SampleView::onRequestViewInRealSpace);
connect(editor, &LayerOrientedSampleEditor::aboutToRemoveItem, this,
&SampleView::onAboutToRemoveItem);
Matthias Puchner
committed
connect(editor, &LayerOrientedSampleEditor::requestCreateNewSample,
sampleSelectionView->newSampleAction(), &QAction::trigger, Qt::QueuedConnection);
connect(editor, &LayerOrientedSampleEditor::modified, m_realSpacePanel->canvas(),
&RealSpaceCanvas::updateScene);
connect(editor, &LayerOrientedSampleEditor::modified, m_document, &ProjectDocument::setModified,
Qt::UniqueConnection);
setCentralWidget(editor);
resetLayout();
}
Matthias Puchner
committed
void SampleView::updateSingleSampleMode()
Matthias Puchner
committed
m_docks->setDockVisible(SAMPLE_LIST, !m_document->singleSampleMode());
void SampleView::onRequestViewInRealSpace(SampleItem itemToView)
Matthias Puchner
committed
{
RealSpaceCanvas::ItemForRealSpace itemForRealSpace;
if (auto* p = itemToView.get_if<MultiLayerItem*>())
else if (auto* p = itemToView.get_if<LayerItem*>())
else if (auto* p = itemToView.get_if<ParticleLayoutItem*>())
else if (auto* p = itemToView.get_if<ItemWithParticles*>())
itemForRealSpace = p;
else
return;
Matthias Puchner
committed
m_docks->setDockVisible(REALSPACEPANEL);
m_realSpacePanel->canvas()->setCurrentItem(itemForRealSpace);
Matthias Puchner
committed
}
void SampleView::onAboutToRemoveItem(SampleItem itemToRemove)
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// If an item shall be deleted from the sample, check whether RealSpace is affected.
// Its current item could be itemToRemmove itself, or it could be a child of itemToRemove.
// -- for convenience access later on
auto* canvas = m_realSpacePanel->canvas();
auto* currentAsLayer = canvas->currentItemAs<LayerItem*>();
auto* currentAsLayout = canvas->currentItemAs<ParticleLayoutItem*>();
auto* currentAsParticle = canvas->currentItemAs<ItemWithParticles*>();
const auto resetIf = [&](bool b) {
if (b)
canvas->resetScene();
};
if (itemToRemove.get_if<MultiLayerItem*>()) {
// -- itemToRemove is a multilayer. In this case: always reset
canvas->resetScene();
} else if (auto* layerToRemove = itemToRemove.get_if<LayerItem*>()) {
// -- itemToRemove is a layer
resetIf(layerToRemove == currentAsLayer);
resetIf(layerToRemove->layouts().contains(currentAsLayout));
resetIf(layerToRemove->itemsWithParticles().contains(currentAsParticle));
} else if (auto* layoutToRemove = itemToRemove.get_if<ParticleLayoutItem*>()) {
// -- itemToRemove is a particle layout
resetIf(layoutToRemove == currentAsLayout);
resetIf(layoutToRemove->containedItemsWithParticles().contains(currentAsParticle));
} else if (auto* particleToRemove = itemToRemove.get_if<ItemWithParticles*>()) {
// -- itemToRemove is a particle
resetIf(particleToRemove == currentAsParticle);
resetIf(particleToRemove->containedItemsWithParticles().contains(currentAsParticle));
}
void SampleView::toggleRealSpaceView()
{
m_docks->toggleDock(REALSPACEPANEL);
}
void SampleView::fillViewMenu(QMenu* menu)
{
m_docks->addDockActionsToMenu(menu);
menu->addSeparator();
auto* action = new QAction(menu);
action->setText("Reset to default layout");
connect(action, &QAction::triggered, this, &SampleView::resetLayout);
menu->addAction(action);
void SampleView::resetLayout()
{
Matthias
committed
m_docks->resetLayout();
tabifyDockWidget(m_docks->findDock(REALSPACEPANEL), m_docks->findDock(PYTHONPANEL));
m_docks->findDock(REALSPACEPANEL)->raise(); // makes first tab active
m_docks->findDock(REALSPACEPANEL)->hide();
m_docks->findDock(PYTHONPANEL)->hide();
if (auto* d = m_docks->findDock(SAMPLE_LIST)) {
if (m_document->singleSampleMode())
d->hide();
else
d->show();
}