Skip to content
Snippets Groups Projects
Commit 3ce2b6d6 authored by Matthias Puchner's avatar Matthias Puchner
Browse files

simplify RealSpace (3D) view - refactoring, mv selection handling out of presentation class

parent f9c1242b
No related branches found
No related tags found
1 merge request!433simplify RealSpace (3D) view part 2 (preparation for using 3D view for layer oriented editor)
......@@ -27,14 +27,14 @@
#include <QMessageBox>
#include <QVBoxLayout>
RealSpaceCanvas::RealSpaceCanvas(QWidget* parent)
RealSpaceCanvas::RealSpaceCanvas(SampleModel* sampleModel, QWidget* parent)
: QWidget(parent)
, m_sampleModel(nullptr)
, m_sampleModel(sampleModel)
, m_view(new GUI::RealSpace::Widget3D)
, m_selectionModel(nullptr)
, m_view_locked(false)
, m_sceneGeometry(new SceneGeometry)
, m_cautionSign(new CautionSign(this))
, m_currentItem(nullptr)
{
auto layout = new QVBoxLayout;
layout->setMargin(0);
......@@ -43,93 +43,23 @@ RealSpaceCanvas::RealSpaceCanvas(QWidget* parent)
setLayout(layout);
}
RealSpaceCanvas::~RealSpaceCanvas() = default;
void RealSpaceCanvas::setModel(SampleModel* sampleModel, QItemSelectionModel* selectionModel)
void RealSpaceCanvas::setCurrentItem(SessionItem* item)
{
if (sampleModel != m_sampleModel) {
if (m_sampleModel)
setConnected(m_sampleModel, false);
m_sampleModel = sampleModel;
if (m_sampleModel)
setConnected(m_sampleModel, true);
}
if (selectionModel != m_selectionModel) {
if (m_selectionModel)
disconnect(m_selectionModel, &QItemSelectionModel::selectionChanged, this,
&RealSpaceCanvas::onSelectionChanged);
m_selectionModel = selectionModel;
if (m_selectionModel)
connect(m_selectionModel, &QItemSelectionModel::selectionChanged, this,
&RealSpaceCanvas::onSelectionChanged);
}
updateToSelection();
}
void RealSpaceCanvas::onSelectionChanged(const QItemSelection&, const QItemSelection&)
{
updateToSelection();
}
void RealSpaceCanvas::updateToSelection()
{
if (!m_selectionModel)
return;
if (!m_view_locked) {
QModelIndexList indices = m_selectionModel->selection().indexes();
if (!indices.empty())
m_currentSelection = FilterPropertyProxy::toSourceIndex(indices.back());
else
m_currentSelection = {};
// if no object is selected then display nothing on canvas
updateScene();
}
}
void RealSpaceCanvas::onDefaultViewAction()
{
defaultView();
}
void RealSpaceCanvas::onSideViewAction()
{
sideView();
}
void RealSpaceCanvas::onTopViewAction()
{
topView();
}
void RealSpaceCanvas::onLockViewAction(bool view_locked)
{
if (m_view_locked != view_locked) {
m_view_locked = view_locked;
updateToSelection();
}
m_currentItem = item;
updateScene();
}
void RealSpaceCanvas::onChangeLayerSizeAction(double layerSizeChangeScale)
void RealSpaceCanvas::changeLayerSize(double layerSizeChangeScale)
{
// when no object is selected --> take no action
if (m_currentSelection == QModelIndex())
if (m_currentItem == nullptr)
return;
m_sceneGeometry->set_layer_size(m_sceneGeometry->layer_size() * layerSizeChangeScale);
updateScene();
}
void RealSpaceCanvas::onSavePictureAction()
void RealSpaceCanvas::savePicture()
{
QPixmap pixmap(this->size());
render(&pixmap, QPoint(), childrenRegion());
......@@ -141,10 +71,23 @@ void RealSpaceCanvas::onRowsAboutToBeRemoved(const QModelIndex& parent, int firs
// clear scene if current selection will be removed
if (!m_sampleModel)
return;
if (m_currentSelection == m_sampleModel->index(first, 0, parent))
const QModelIndex idx = m_sampleModel->index(first, 0, parent);
const auto* itemToBeRemoved = m_sampleModel->itemForIndex(idx);
if (m_currentItem == itemToBeRemoved)
resetScene();
}
void RealSpaceCanvas::showEvent(QShowEvent*)
{
setConnected(m_sampleModel, true);
updateScene();
}
void RealSpaceCanvas::hideEvent(QHideEvent*)
{
setConnected(m_sampleModel, false);
}
void RealSpaceCanvas::savePicture(const QPixmap& pixmap)
{
QString dirname = gSessionData->projectDocument->userExportDir();
......@@ -173,12 +116,12 @@ void RealSpaceCanvas::savePicture(const QPixmap& pixmap)
void RealSpaceCanvas::updateScene()
{
if (!m_currentItem)
return;
QApplication::setOverrideCursor(Qt::WaitCursor);
m_realSpaceModel.reset(new RealSpaceModel);
auto item = m_sampleModel->itemForIndex(m_currentSelection);
if (!item)
return;
RealSpaceBuilder builder3D;
......@@ -186,11 +129,11 @@ void RealSpaceCanvas::updateScene()
m_cautionSign->clear();
// if the view is locked, keep the current orientation of the camera
if (m_view_locked)
builder3D.populate(m_realSpaceModel.get(), *item, *m_sceneGeometry,
builder3D.populate(m_realSpaceModel.get(), *m_currentItem, *m_sceneGeometry,
m_view->cam().getPos());
// otherwise use default orientation of camera
else {
builder3D.populate(m_realSpaceModel.get(), *item, *m_sceneGeometry);
builder3D.populate(m_realSpaceModel.get(), *m_currentItem, *m_sceneGeometry);
defaultView(); // Enforces default view and also sets the zoomLevel to default i.e. 0
}
} catch (const std::exception& ex) {
......@@ -207,7 +150,7 @@ void RealSpaceCanvas::resetScene()
{
m_realSpaceModel.reset();
m_view->setModel(nullptr);
m_currentSelection = {};
m_currentItem = nullptr;
}
void RealSpaceCanvas::defaultView()
......@@ -242,7 +185,7 @@ void RealSpaceCanvas::setConnected(SampleModel* model, bool makeConnected)
connect(model, &SampleModel::modelReset, this, &RealSpaceCanvas::resetScene,
Qt::UniqueConnection);
connect(
model, &SampleModel::modelAboutToBeReset, this, [&]() { m_currentSelection = {}; },
model, &SampleModel::modelAboutToBeReset, this, [&]() { m_currentItem = nullptr; },
Qt::UniqueConnection);
} else {
......
......@@ -15,14 +15,13 @@
#ifndef BORNAGAIN_GUI_VIEW_REALSPACE_REALSPACECANVAS_H
#define BORNAGAIN_GUI_VIEW_REALSPACE_REALSPACECANVAS_H
#include <QItemSelectionModel>
#include <QModelIndex>
#include <QWidget>
#include <memory>
class SampleModel;
class RealSpaceModel;
class CautionSign;
class SessionItem;
namespace GUI::RealSpace {
class Widget3D;
}
......@@ -60,44 +59,35 @@ class RealSpaceCanvas : public QWidget {
Q_OBJECT
public:
RealSpaceCanvas(QWidget* parent = nullptr);
~RealSpaceCanvas();
void setModel(SampleModel* sampleModel = nullptr,
QItemSelectionModel* selectionModel = nullptr);
public slots:
void onSelectionChanged(const QItemSelection&, const QItemSelection&);
void updateToSelection();
void onDefaultViewAction();
void onSideViewAction();
void onTopViewAction();
void onLockViewAction(bool view_locked);
void onChangeLayerSizeAction(double layer_size_scale);
void onSavePictureAction();
void onRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last);
RealSpaceCanvas(SampleModel* sampleModel, QWidget* parent = nullptr);
private slots:
void updateScene();
void resetScene();
void setCurrentItem(SessionItem* item);
void defaultView();
void sideView();
void topView();
void changeLayerSize(double layer_size_scale);
void savePicture();
protected:
virtual void showEvent(QShowEvent*) override;
virtual void hideEvent(QHideEvent*) override;
private:
void updateScene();
void resetScene();
void onRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last);
void setConnected(SampleModel* model, bool makeConnected);
void savePicture(const QPixmap& pixmap);
SampleModel* m_sampleModel;
QModelIndex m_currentSelection;
GUI::RealSpace::Widget3D* m_view;
std::unique_ptr<RealSpaceModel> m_realSpaceModel;
QItemSelectionModel* m_selectionModel;
bool m_view_locked;
std::unique_ptr<SceneGeometry> m_sceneGeometry;
CautionSign* m_cautionSign;
void savePicture(const QPixmap& pixmap);
SessionItem* m_currentItem;
};
#endif // BORNAGAIN_GUI_VIEW_REALSPACE_REALSPACECANVAS_H
......@@ -17,12 +17,8 @@
#include "GUI/View/Realspace/RealSpaceCanvas.h"
#include <QVBoxLayout>
RealSpacePanel::RealSpacePanel(SampleModel* sampleModel, QItemSelectionModel* selectionModel,
QWidget* parent)
: QWidget(parent)
, m_canvas(new RealSpaceCanvas)
, m_sampleModel(sampleModel)
, m_selectionModel(selectionModel)
RealSpacePanel::RealSpacePanel(SampleModel* sampleModel, QWidget* parent)
: QWidget(parent), m_canvas(new RealSpaceCanvas(sampleModel))
{
setWindowTitle("Real Space");
setObjectName("Sample3DPanel");
......@@ -38,26 +34,25 @@ RealSpacePanel::RealSpacePanel(SampleModel* sampleModel, QItemSelectionModel* se
};
auto* action = createAction("Save Picture", "Save 3D real space view as .png file");
connect(action, &QAction::triggered, m_canvas, &RealSpaceCanvas::onSavePictureAction);
connect(action, &QAction::triggered, m_canvas, QOverload<>::of(&RealSpaceCanvas::savePicture));
action = createAction("Default View", "Reset view and zoom level to default");
connect(action, &QAction::triggered, m_canvas, &RealSpaceCanvas::onDefaultViewAction);
connect(action, &QAction::triggered, m_canvas, &RealSpaceCanvas::defaultView);
action = createAction("Side View", "View sample from the side at current zoom level");
connect(action, &QAction::triggered, m_canvas, &RealSpaceCanvas::onSideViewAction);
connect(action, &QAction::triggered, m_canvas, &RealSpaceCanvas::sideView);
action = createAction("Top View", "View sample from the top at current zoom level");
connect(action, &QAction::triggered, m_canvas, &RealSpaceCanvas::onTopViewAction);
connect(action, &QAction::triggered, m_canvas, &RealSpaceCanvas::topView);
action = createAction("Enlarge", "Increase layer size");
connect(action, &QAction::triggered, [this]() { m_canvas->onChangeLayerSizeAction(1.25); });
connect(action, &QAction::triggered, [this]() { m_canvas->changeLayerSize(1.25); });
action = createAction("Reduce", "Decrease layer size");
connect(action, &QAction::triggered, [this]() { m_canvas->onChangeLayerSizeAction(0.8); });
connect(action, &QAction::triggered, [this]() { m_canvas->changeLayerSize(0.8); });
action = createAction("Lock View", "Lock/unlock current sample selection");
action->setCheckable(true);
connect(action, &QAction::triggered, m_canvas, &RealSpaceCanvas::onLockViewAction);
m_lockViewAction = createAction("Lock View", "Lock/unlock current sample selection");
m_lockViewAction->setCheckable(true);
auto* mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0);
......@@ -72,12 +67,12 @@ QSize RealSpacePanel::sizeHint() const
return QSize(300, 300);
}
void RealSpacePanel::showEvent(QShowEvent*)
RealSpaceCanvas* RealSpacePanel::canvas()
{
m_canvas->setModel(m_sampleModel, m_selectionModel);
return m_canvas;
}
void RealSpacePanel::hideEvent(QHideEvent*)
bool RealSpacePanel::isViewLocked() const
{
m_canvas->setModel(nullptr, nullptr);
return m_lockViewAction->isChecked();
}
......@@ -28,18 +28,16 @@ class RealSpacePanel : public QWidget {
Q_OBJECT
public:
RealSpacePanel(SampleModel* sampleModel, QItemSelectionModel* selectionModel, QWidget* parent);
RealSpacePanel(SampleModel* sampleModel, QWidget* parent);
QSize sizeHint() const override;
RealSpaceCanvas* canvas();
protected:
void showEvent(QShowEvent*) override;
void hideEvent(QHideEvent*) override;
bool isViewLocked() const;
private:
RealSpaceCanvas* m_canvas;
SampleModel* m_sampleModel;
QItemSelectionModel* m_selectionModel;
QAction* m_lockViewAction;
};
#endif // BORNAGAIN_GUI_VIEW_SAMPLEDESIGNER_REALSPACEPANEL_H
......@@ -16,7 +16,9 @@
#include "GUI/Model/Group/FilterPropertyProxy.h"
#include "GUI/Model/Project/ProjectDocument.h"
#include "GUI/Model/Sample/MultiLayerItem.h"
#include "GUI/Model/Sample/SampleModel.h"
#include "GUI/View/Common/DocksController.h"
#include "GUI/View/Realspace/RealSpaceCanvas.h"
#include "GUI/View/SampleDesigner/DesignerScene.h"
#include "GUI/View/SampleDesigner/DesignerView.h"
#include "GUI/View/SampleDesigner/LayerOrientedSampleEditor.h"
......@@ -61,14 +63,13 @@ void SampleView::initNetOrientedEditor()
auto* treeWidget = new SampleTreeWidget(this, m_document->sampleModel());
auto* propertyWidget = new SamplePropertyWidget(treeWidget->treeView()->selectionModel(), this);
auto* scriptPanel = new ScriptPanel(m_document->sampleModel(), this);
auto* realSpacePanel = new RealSpacePanel(m_document->sampleModel(),
treeWidget->treeView()->selectionModel(), this);
m_realSpacePanel = new RealSpacePanel(m_document->sampleModel(), this);
m_docks->addWidget(TOOLBOX, toolBox, Qt::LeftDockWidgetArea);
m_docks->addWidget(SAMPLE_TREE, treeWidget, Qt::RightDockWidgetArea);
m_docks->addWidget(PROPERTY_EDITOR, propertyWidget, Qt::RightDockWidgetArea);
m_docks->addWidget(INFO, scriptPanel, Qt::BottomDockWidgetArea);
m_docks->addWidget(REALSPACEPANEL, realSpacePanel, Qt::BottomDockWidgetArea);
m_docks->addWidget(REALSPACEPANEL, m_realSpacePanel, Qt::BottomDockWidgetArea);
connect(scriptPanel, &ScriptPanel::widgetHeightRequest, m_docks,
&DocksController::setDockHeightForWidget);
......@@ -92,6 +93,8 @@ void SampleView::initNetOrientedEditor()
connect(m_toolBar, &SampleToolBar::changeScale, designerView, &DesignerView::onChangeScale);
connect(designerScene, &DesignerScene::selectionModeChangeRequest, designerView,
&DesignerView::onSelectionMode);
connect(treeWidget->treeView()->selectionModel(), &QItemSelectionModel::selectionChanged, this,
&SampleView::onSampleTreeViewSelectionChanged);
addToolBar(m_toolBar);
......@@ -131,12 +134,12 @@ void SampleView::initLayerOrientedEditor()
QSizePolicy::MinimumExpanding);
auto* scriptPanel = new ScriptPanel(m_document->sampleModel(), this);
auto* realSpacePanel = new RealSpacePanel(m_document->sampleModel(), nullptr, this);
m_realSpacePanel = new RealSpacePanel(m_document->sampleModel(), this);
sampleSelectionPane->setWindowTitle("Samples");
m_docks->addWidget(SAMPLE_LIST, sampleSelectionPane, Qt::LeftDockWidgetArea);
m_docks->addWidget(REALSPACEPANEL, realSpacePanel, Qt::BottomDockWidgetArea);
m_docks->addWidget(REALSPACEPANEL, m_realSpacePanel, Qt::BottomDockWidgetArea);
m_docks->addWidget(INFO, scriptPanel, Qt::BottomDockWidgetArea);
connect(scriptPanel, &ScriptPanel::widgetHeightRequest, m_docks,
......@@ -181,6 +184,21 @@ void SampleView::updateFunctionalities()
}
}
void SampleView::onSampleTreeViewSelectionChanged(const QItemSelection& selected,
const QItemSelection&)
{
if (m_realSpacePanel->isViewLocked())
return;
if (selected.indexes().empty())
return;
const QModelIndex currentIndex = FilterPropertyProxy::toSourceIndex(selected.indexes().back());
auto* item = m_document->sampleModel()->itemForIndex(currentIndex);
if (item)
m_realSpacePanel->canvas()->setCurrentItem(item);
}
void SampleView::toggleRealSpaceView()
{
m_docks->toggleDock(REALSPACEPANEL);
......
......@@ -20,6 +20,8 @@
class DocksController;
class ProjectDocument;
class SampleToolBar;
class RealSpacePanel;
class QItemSelection;
class SampleView : public QMainWindow {
Q_OBJECT
......@@ -37,10 +39,12 @@ private:
void initLayerOrientedEditor();
void deleteEditor();
void updateFunctionalities();
void onSampleTreeViewSelectionChanged(const QItemSelection& selected, const QItemSelection&);
DocksController* m_docks = nullptr;
ProjectDocument* m_document = nullptr;
SampleToolBar* m_toolBar = nullptr;
RealSpacePanel* m_realSpacePanel = nullptr;
bool m_useLayerOrientedEditor = false;
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment