diff --git a/Modules/RenderWindowManager/files.cmake b/Modules/RenderWindowManager/files.cmake index b2931816b9..5e95f08b7a 100644 --- a/Modules/RenderWindowManager/files.cmake +++ b/Modules/RenderWindowManager/files.cmake @@ -1,18 +1,19 @@ set(H_FILES - include/QmitkVisibilityDelegate.h include/QmitkRenderWindowDataModel.h include/mitkRenderWindowLayerController.h + include/mitkRenderWindowViewDirectionController.h + include/mitkRenderWindowLayerUtilities.h ) set(CPP_FILES - QmitkVisibilityDelegate.cpp QmitkRenderWindowDataModel.cpp mitkRenderWindowLayerController.cpp + mitkRenderWindowViewDirectionController.cpp + mitkRenderWindowLayerUtilities.cpp ) set(MOC_H_FILES - include/QmitkVisibilityDelegate.h include/QmitkRenderWindowDataModel.h ) diff --git a/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h b/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h index e963637401..09a95b8c52 100644 --- a/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h +++ b/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h @@ -1,78 +1,69 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef QmitkRenderWindowDataModel_h -#define QmitkRenderWindowDataModel_h +#ifndef QMITKRENDERWINDOWDATAMODEL_H +#define QMITKRENDERWINDOWDATAMODEL_H // render window manager #include "MitkRenderWindowManagerExports.h" +#include "mitkRenderWindowLayerUtilities.h" //mitk +#include #include // qt #include /* * @brief This class extends the 'QAbstractItemModel' to meet the specific requirements of the QmitkRenderWindowDataModel. */ class MITKRENDERWINDOWMANAGER_EXPORT QmitkRenderWindowDataModel : public QAbstractTableModel { Q_OBJECT public: - typedef std::string RenderWindowName; - typedef std::vector DataNodeNamesVector; - // TODO: use std::map RenderWindowDataNodesMap; - QmitkRenderWindowDataModel(QObject* parent = nullptr); - virtual ~QmitkRenderWindowDataModel() {}; + virtual ~QmitkRenderWindowDataModel(); ////////////////////////////////////////////////////////////////////////// /// overridden functions from QAbstractItemModel ////////////////////////////////////////////////////////////////////////// virtual Qt::ItemFlags flags(const QModelIndex &index) const override; virtual QVariant data(const QModelIndex &index, int role) const override; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override; virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; ////////////////////////////////////////////////////////////////////////// /// end override ///////////////////////////////////////////////////////////////////////// + // currently not needed (uses data storage of the layer controller (e.g. for call of GetLayerStack)) void SetDataStorage(mitk::DataStorage::Pointer dataStorage); - void SetCurrentRenderWindowName(std::string renderWindowName); - - void InsertLayerNode(std::string dataNodeName, std::string renderer); - void MoveNodeUp(int rowIndex, std::string dataNodeName, std::string renderer); - void MoveNodeDown(int rowIndex, std::string dataNodeName, std::string renderer); - -signals: - void VisibilityChanged(int index, bool isDataNodeVisible); + void SetCurrentRenderer(std::string rendererName); + void DataChanged(const mitk::DataNode* dataNode); private: mitk::DataStorage::Pointer m_DataStorage; - // map from render window name / id to vector of data node names of the specific render window - RenderWindowDataNodesMap m_RenderWindowDataNodesMap; - RenderWindowName m_CurrentRenderWindowName; + mitk::BaseRenderer::Pointer m_BaseRenderer; + RenderWindowLayerUtilities::LayerStack m_TempLayerStack; }; -#endif // QmitkRenderWindowDataModel_h +#endif // QMITKRENDERWINDOWDATAMODEL_H diff --git a/Modules/RenderWindowManager/include/QmitkVisibilityDelegate.h b/Modules/RenderWindowManager/include/QmitkVisibilityDelegate.h deleted file mode 100644 index 29fdf5a975..0000000000 --- a/Modules/RenderWindowManager/include/QmitkVisibilityDelegate.h +++ /dev/null @@ -1,57 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ - -#ifndef QmitkVisibilityDelegate_h -#define QmitkVisibilityDelegate_h - -// render window manager -#include "MitkRenderWindowManagerExports.h" - -// qt -#include -#include - -#include - -/* -* @brief -*/ -class MITKRENDERWINDOWMANAGER_EXPORT QmitkVisibilityDelegate : public QStyledItemDelegate -{ - Q_OBJECT - -public: - - QmitkVisibilityDelegate(QObject* parent = 0); - - // Create Editor when we construct - QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - - //// Then, we set the Editor - //void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE; - // - //// When we modify data, this model reflect the change - //void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE; - - // Give the SpinBox the info on size and location - void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - - void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - - bool editorEvent(QEvent *event, QAbstractItemModel* model, const QStyleOptionViewItem &option, const QModelIndex &index); -}; - -#endif //QmitkVisabilityDelegate_h diff --git a/Modules/RenderWindowManager/include/mitkRenderWindowLayerController.h b/Modules/RenderWindowManager/include/mitkRenderWindowLayerController.h index 03c78a2098..7691dbd68f 100644 --- a/Modules/RenderWindowManager/include/mitkRenderWindowLayerController.h +++ b/Modules/RenderWindowManager/include/mitkRenderWindowLayerController.h @@ -1,145 +1,128 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKRENDERWINDOWLAYERCONTROLLER_H #define MITKRENDERWINDOWLAYERCONTROLLER_H // render window manager #include "MitkRenderWindowManagerExports.h" -#include // mitk #include #include #include namespace mitk { /* - * TODO: generate layer stack on demand or keep layer stack of each render window on hand - * * TODO: really layer 0 (zero)? * The base data node of a renderer is supposed to be on layer 0 (zero), which should be the lowest layer in a render window. * * Functions with 'const mitk::BaseRenderer* renderer' have 'nullptr' as their default argument. Using the nullptr * these functions operate on all base renderer. */ class MITKRENDERWINDOWMANAGER_EXPORT RenderWindowLayerController { public: - typedef std::vector RendererVector; - typedef std::map LayerStack; + typedef std::vector RendererVector; RenderWindowLayerController(); - RenderWindowLayerController(std::shared_ptr renderWindowDataModel); - virtual ~RenderWindowLayerController(); /** * @brief set the data storage on which to work */ void SetDataStorage(DataStorage::Pointer dataStorage); DataStorage::Pointer GetDataStorage() { return m_DataStorage; }; /** * @brief set the controlled base renderer by specifying the corresponding render windows */ - void SetControlledRenderer(const mitk::RenderingManager::RenderWindowVector &renderWindows); + void SetControlledRenderer(const RenderingManager::RenderWindowVector &renderWindows); /** * @brief set the controlled base renderer */ - void SetControlledRenderer(RendererVector renderWindows); + void SetControlledRenderer(RendererVector controlledRenderer); RendererVector GetControlledRenderer() { return m_ControlledRenderer; }; - //itkGetMacro(ControlledRenderer, RendererVector); // wrapper functions to modify the layer order / visibility of render window data /** * @brief set the given node as the base node of the given renderer (nullptr = all renderer) */ - void SetBaseDataNode(DataNode* dataNode, const mitk::BaseRenderer* renderer = nullptr); + void SetBaseDataNode(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief insert the given data node at the specified layer for the given renderer (nullptr = all renderer) * * 'layer = -1' (default) inserts the given data node at the top of the node stack (topmost layer) * new layer nodes have to have their 'fixedLayer' property set to true */ - void InsertLayerNode(DataNode* dataNode, int layer = -1, const mitk::BaseRenderer* renderer = nullptr); + void InsertLayerNode(DataNode* dataNode, int layer = -1, const BaseRenderer* renderer = nullptr); /** * @brief */ - void RemoveLayerNode(int rowIndex, DataNode* dataNode, const mitk::BaseRenderer* renderer = nullptr); + void RemoveLayerNode(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief set the node in the given renderer as the topmost layer (nullptr = all renderer) * * @return true, if the node was successfully moved, false otherwise */ - bool MoveNodeToFront(DataNode* dataNode, const mitk::BaseRenderer* renderer = nullptr); + void MoveNodeToFront(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief set the node in the given renderer as the lowermost layer (nullptr = all renderer) * * @return true, if the node was successfully moved, false otherwise */ - bool MoveNodeToBack(DataNode* dataNode, const mitk::BaseRenderer* renderer = nullptr); + void MoveNodeToBack(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief move the node in the given renderer one layer down (nullptr = all renderer) * * @return true, if the node was successfully moved, false otherwise */ - bool MoveNodeUp(int rowIndex, DataNode* dataNode, const mitk::BaseRenderer* renderer = nullptr); + void MoveNodeUp(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief move the node in the given renderer one layer up (nullptr = all renderer) * * @return true, if the node was successfully moved, false otherwise */ - bool MoveNodeDown(int rowIndex, DataNode* dataNode, const mitk::BaseRenderer* renderer = nullptr); + void MoveNodeDown(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief set the visibility of the given data node for the given renderer (nullptr = all renderer) */ - void SetVisibilityOfDataNode(bool visiblity, DataNode* dataNode, const mitk::BaseRenderer* renderer = nullptr); + void SetVisibilityOfDataNode(bool visiblity, DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief hide the given data node by setting the 'fixedLayer'property and the 'visible' property of this data node for * all controlled renderer to false * * setting the 'visible' property of a data node for a certain renderer will overwrite the same property of the common renderer */ void HideDataNodeInAllRenderer(const DataNode* dataNode); /** * @brief reset the given render window (nullptr = all renderer): * if 'onlyVisibility = true': set all data nodes for the render window to invisible, except for the base node * if 'onlyVisibility = false': remove all data nodes from the render window, except for the base node */ - void ResetRenderer(bool onlyVisibility = true, const mitk::BaseRenderer* renderer = nullptr); - /** - * @brief return the stack of layers of the given renderer as std::map, which guarantees ordering of the layers - * stacked layers are only included, if they have set their 'fixedLayer' property to true - * - * if 'renderer" = nullptr: a layer stack won't be created and an empty 'LayerStack' will be returned - * if 'withBaseNode' = true: include the base node (layer = 0) in the layer stack, if existing - * if 'withBaseNode' = false: exclude the base node (layer = 0) from the layer stack - */ - LayerStack GetLayerStack(const mitk::BaseRenderer* renderer, bool withBaseNode); + void ResetRenderer(bool onlyVisibility = true, const BaseRenderer* renderer = nullptr); private: - void InsertLayerNodeInternal(DataNode* dataNode, int layer, const mitk::BaseRenderer* renderer = nullptr); + void InsertLayerNodeInternal(DataNode* dataNode, int layer, const BaseRenderer* renderer = nullptr); - std::shared_ptr m_RenderWindowDataModel; DataStorage::Pointer m_DataStorage; RendererVector m_ControlledRenderer; }; } // namespace mitk #endif // MITKRENDERWINDOWLAYERCONTROLLER_H diff --git a/Modules/RenderWindowManager/include/mitkRenderWindowLayerUtilities.h b/Modules/RenderWindowManager/include/mitkRenderWindowLayerUtilities.h new file mode 100644 index 0000000000..c7c9fe18da --- /dev/null +++ b/Modules/RenderWindowManager/include/mitkRenderWindowLayerUtilities.h @@ -0,0 +1,47 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef MITKRENDERWINDOWLAYERUTILITIES_H +#define MITKRENDERWINDOWLAYERUTILITIES_H + +// render window manager +#include "MitkRenderWindowManagerExports.h" + +// mitk +#include +#include + +/** +* @brief Render window layer helper functions to retrieve the currently valid layer stack +*/ +namespace RenderWindowLayerUtilities +{ + typedef std::map> LayerStack; + + + /** + * @brief return the stack of layers of the given renderer as std::map, which guarantees ordering of the layers + * stacked layers are only included, if they have set their 'fixedLayer' property to true + * + * if 'renderer" = nullptr: a layer stack won't be created and an empty 'LayerStack' will be returned + * if 'withBaseNode' = true: include the base node (layer = 0) in the layer stack, if existing + * if 'withBaseNode' = false: exclude the base node (layer = 0) from the layer stack + */ + MITKRENDERWINDOWMANAGER_EXPORT LayerStack GetLayerStack(const mitk::DataStorage* dataStorage, const mitk::BaseRenderer* renderer, bool withBaseNode); + +} // namespace RenderWindowLayerUtilities + +#endif // MITKRENDERWINDOWLAYERUTILITIES_H diff --git a/Modules/RenderWindowManager/include/mitkRenderWindowViewDirectionController.h b/Modules/RenderWindowManager/include/mitkRenderWindowViewDirectionController.h new file mode 100644 index 0000000000..75a70dd124 --- /dev/null +++ b/Modules/RenderWindowManager/include/mitkRenderWindowViewDirectionController.h @@ -0,0 +1,70 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef MITKRENDERWINDOWVIEWDIRECTIONCONTROLLER_H +#define MITKRENDERWINDOWVIEWDIRECTIONCONTROLLER_H + +// render window manager +#include "MitkRenderWindowManagerExports.h" + +// mitk +#include +#include + +namespace mitk +{ + /* + */ + class MITKRENDERWINDOWMANAGER_EXPORT RenderWindowViewDirectionController + { + public: + + typedef std::vector RendererVector; + + RenderWindowViewDirectionController(); + virtual ~RenderWindowViewDirectionController(); + /** + * @brief set the data storage on which to work + */ + void SetDataStorage(DataStorage::Pointer dataStorage); + DataStorage::Pointer GetDataStorage() { return m_DataStorage; }; + /** + * @brief set the controlled base renderer by specifying the corresponding render windows + */ + void SetControlledRenderer(const RenderingManager::RenderWindowVector &renderWindows); + /** + * @brief set the controlled base renderer + */ + void SetControlledRenderer(RendererVector controlledRenderer); + RendererVector GetControlledRenderer() { return m_ControlledRenderer; }; + + // wrapper functions to modify the view direction + /** + * @brief set the view direction for the given renderer (nullptr = all renderer) + */ + void SetViewDirectionOfRenderer(const std::string &viewDirection, BaseRenderer* renderer = nullptr); + + private: + + void InitializeViewByBoundingObjects(const BaseRenderer* renderer); + + DataStorage::Pointer m_DataStorage; + RendererVector m_ControlledRenderer; + }; + +} // namespace mitk + +#endif // MITKRENDERWINDOWVIEWDIRECTIONCONTROLLER_H diff --git a/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp b/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp index e871d74f0d..f40cf5bc5d 100644 --- a/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp +++ b/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp @@ -1,226 +1,204 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include -#include - #include "QmitkRenderWindowDataModel.h" -// mitk -#include - -QmitkRenderWindowDataModel::QmitkRenderWindowDataModel(QObject* parent) +QmitkRenderWindowDataModel::QmitkRenderWindowDataModel(QObject* parent /*= nullptr*/) : QAbstractTableModel(parent) { - + // nothing here } -int QmitkRenderWindowDataModel::rowCount(const QModelIndex &parent) const +QmitkRenderWindowDataModel::~QmitkRenderWindowDataModel() { - if (parent.isValid()) + if (m_DataStorage.IsNotNull()) { - return 0; + m_DataStorage->ChangedNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); + m_DataStorage->RemoveNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); } +} - std::map::const_iterator iterator = m_RenderWindowDataNodesMap.find(m_CurrentRenderWindowName); - if (iterator == m_RenderWindowDataNodesMap.end()) +int QmitkRenderWindowDataModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const +{ + if (parent.isValid()) { return 0; } - else - { - return iterator->second.size(); - } + + return static_cast(m_TempLayerStack.size()); } -int QmitkRenderWindowDataModel::columnCount(const QModelIndex &parent) const +int QmitkRenderWindowDataModel::columnCount(const QModelIndex &parent /*= QModelIndex()*/) const { if (parent.isValid()) { return 0; } return 2; } QVariant QmitkRenderWindowDataModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) { return QVariant(); } - // find the list of data nodes of the given render window - std::map::const_iterator iterator = m_RenderWindowDataNodesMap.find(m_CurrentRenderWindowName); - if (iterator != m_RenderWindowDataNodesMap.end() - && static_cast(index.row()) < iterator->second.size()) + if ((index.row()) < static_cast(m_TempLayerStack.size())) { - const std::string &dataNodeName = iterator->second.at(iterator->second.size() - index.row() - 1); - // different behavior for the columns - switch (index.column()) + RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_TempLayerStack.begin(); + std::advance(layerStackIt, index.row()); + mitk::DataNode* dataNode = layerStackIt->second; + if (Qt::CheckStateRole == role && 0 == index.column()) { - case 0: - if (role == Qt::CheckStateRole) + bool visibility = false; + dataNode->GetVisibility(visibility, m_BaseRenderer); + if (visibility) { - const mitk::DataNode* selectedDataNode = m_DataStorage->GetNamedNode(dataNodeName); - const mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_CurrentRenderWindowName); - - bool visibility = false; - // TODO: use the current renderer - selectedDataNode->GetVisibility(visibility, selectedRenderer); - if (visibility) - { - return Qt::Checked; - } - else - { - return Qt::Unchecked; - } + return Qt::Checked; } - else if (role == Qt::ToolTipRole) + else { - return QVariant("Show/hide data node."); + return Qt::Unchecked; } - break; - case 1: - if (role == Qt::DisplayRole) + } + else if (Qt::DisplayRole == role && 1 == index.column()) + { + return QVariant(QString::fromStdString(dataNode->GetName())); + } + else if (Qt::ToolTipRole == role) + { + if (0 == index.column()) { - return QVariant(QString::fromStdString(dataNodeName)); + return QVariant("Show/hide data node."); } - else if (role == Qt::ToolTipRole) + else if (1 == index.column()) { return QVariant("Name of the data node."); } } + else if (Qt::UserRole == role) + { + // user role always returns the data node name, as the name is needed to manipulate a data node + return QVariant(QString::fromStdString(dataNode->GetName())); + } } return QVariant(); } Qt::ItemFlags QmitkRenderWindowDataModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - if (index.column() == 0) + if (0 == index.column()) { flags |= Qt::ItemIsUserCheckable; } return flags; } QVariant QmitkRenderWindowDataModel::headerData(int section, Qt::Orientation orientation, int role) const { if (Qt::Horizontal == orientation && Qt::DisplayRole == role) { - if (section == 0) + if (1 == section) { return QVariant("Visibility"); } - else if (section == 1) + else if (1 == section) { return QVariant("Data node"); } } return QVariant(); } -bool QmitkRenderWindowDataModel::setData(const QModelIndex &index, const QVariant &value, int role) +bool QmitkRenderWindowDataModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) { if (!index.isValid()) { return false; } - // find the list of data nodes of the given render window - std::map::const_iterator iterator = m_RenderWindowDataNodesMap.find(m_CurrentRenderWindowName); - if (iterator != m_RenderWindowDataNodesMap.end() - && static_cast(index.row()) < iterator->second.size()) + if ((index.row()) < static_cast(m_TempLayerStack.size())) { - + RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_TempLayerStack.begin(); + std::advance(layerStackIt, index.row()); + mitk::DataNode* dataNode = layerStackIt->second; if (Qt::CheckStateRole == role) { Qt::CheckState newCheckState = static_cast(value.toInt()); - // retrieve the data node from the data storage - const std::string &dataNodeName = iterator->second.at(iterator->second.size() - index.row() - 1); - mitk::DataNode* selectedDataNode = m_DataStorage->GetNamedNode(dataNodeName); - const mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_CurrentRenderWindowName); - if (Qt::PartiallyChecked == newCheckState || Qt::Checked == newCheckState) { - selectedDataNode->SetVisibility(true, selectedRenderer); + dataNode->SetVisibility(true, m_BaseRenderer); } else { - selectedDataNode->SetVisibility(false, selectedRenderer); + dataNode->SetVisibility(false, m_BaseRenderer); } emit dataChanged(index, index); - mitk::RenderingManager::GetInstance()->RequestUpdate(selectedRenderer->GetRenderWindow()); + mitk::RenderingManager::GetInstance()->RequestUpdate(m_BaseRenderer->GetRenderWindow()); return true; } } return false; } void QmitkRenderWindowDataModel::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { if (m_DataStorage != dataStorage) { + // given data storage is a new data storage + if (m_DataStorage.IsNotNull()) + { + // remove listener from old data storage + m_DataStorage->ChangedNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); + m_DataStorage->RemoveNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); + } // set the new data storage m_DataStorage = dataStorage; + // register new data storage listener + if (m_DataStorage.IsNotNull()) + { + m_DataStorage->ChangedNodeEvent.AddListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); + m_DataStorage->RemoveNodeEvent.AddListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); + } + DataChanged(nullptr); } } -void QmitkRenderWindowDataModel::SetCurrentRenderWindowName(std::string renderWindowName) -{ - m_CurrentRenderWindowName = renderWindowName; - - int numberOfRows = m_RenderWindowDataNodesMap[m_CurrentRenderWindowName].size(); - - // notify view, so that the table will be filled with the nodes information of the newly selected renderer - emit dataChanged(createIndex(0, 0), createIndex(numberOfRows, columnCount())); -} - -void QmitkRenderWindowDataModel::InsertLayerNode(std::string dataNodeName, std::string renderer) -{ - // checking for the node list of the given renderer - // checking with [] creates an empty 'DataNodeNamesVector' if the renderer is currently not used as a key - DataNodeNamesVector &dataNodeNamesVector = m_RenderWindowDataNodesMap[renderer]; - beginInsertRows(QModelIndex(), 0, 0); - dataNodeNamesVector.push_back(dataNodeName); - endInsertRows(); -} - -void QmitkRenderWindowDataModel::MoveNodeUp(int rowIndex, std::string dataNodeName, std::string renderer) +void QmitkRenderWindowDataModel::SetCurrentRenderer(std::string renderWindowName) { - std::map::iterator iterator = m_RenderWindowDataNodesMap.find(renderer); - if (iterator != m_RenderWindowDataNodesMap.end()) + m_BaseRenderer = mitk::BaseRenderer::GetByName(renderWindowName); + if (m_DataStorage.IsNotNull()) { - // swap item at 'dataNodeName' with the previous data node in the vector - std::swap(iterator->second[rowIndex], iterator->second[rowIndex - 1]); - emit dataChanged(createIndex(rowIndex, 1), createIndex(rowIndex - 1, 1)); + DataChanged(nullptr); } } -void QmitkRenderWindowDataModel::MoveNodeDown(int rowIndex, std::string dataNodeName, std::string renderer) +void QmitkRenderWindowDataModel::DataChanged(const mitk::DataNode* /*dataNode*/) { - std::map::iterator iterator = m_RenderWindowDataNodesMap.find(renderer); - if (iterator != m_RenderWindowDataNodesMap.end()) + if (m_BaseRenderer.IsNotNull()) { - // swap item at 'dataNodeName' with the next data node in the vector - std::swap(iterator->second[rowIndex], iterator->second[rowIndex + 1]); - emit dataChanged(createIndex(rowIndex, 1), createIndex(rowIndex + 1, 1)); + // update the model, so that the table will be filled with the nodes information of the new data storage + beginResetModel(); + // get the current layer stack of the given base renderer + m_TempLayerStack = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, m_BaseRenderer, true); + endResetModel(); } } diff --git a/Modules/RenderWindowManager/src/QmitkVisibilityDelegate.cpp b/Modules/RenderWindowManager/src/QmitkVisibilityDelegate.cpp deleted file mode 100644 index 19be4b136b..0000000000 --- a/Modules/RenderWindowManager/src/QmitkVisibilityDelegate.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*=================================================================== - -The Medical Imaging Interaction Toolkit (MITK) - -Copyright (c) German Cancer Research Center, -Division of Medical and Biological Informatics. -All rights reserved. - -This software is distributed WITHOUT ANY WARRANTY; without -even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. - -See LICENSE.txt or http://www.mitk.org for details. - -===================================================================*/ - -#include "QmitkVisibilityDelegate.h" - -// qt -#include -#include -#include -#include -#include -#include -#include - -static QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options) -{ - QStyleOptionButton check_box_style_option; - QRect check_box_rect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &check_box_style_option); - QPoint check_box_point(view_item_style_options.rect.x() + - view_item_style_options.rect.width() / 2 - - check_box_rect.width() / 2, - view_item_style_options.rect.y() + - view_item_style_options.rect.height() / 2 - - check_box_rect.height() / 2); - return QRect(check_box_point, check_box_rect.size()); -} - -QmitkVisibilityDelegate::QmitkVisibilityDelegate(QObject* parent) - : QStyledItemDelegate(parent) -{ - // nothing here -} - -QWidget* QmitkVisibilityDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const -{ - QCheckBox* editor = new QCheckBox(parent); -// editor->setFrame(false); -// editor->setMinimum(0); -// editor->setMaximum(100); -// - return editor; -} - -//void QmitkVisibilityDelegate::setEditorData(QWidget *editor, -// const QModelIndex &index) const -//{ -// int value = index.model()->data(index, Qt::EditRole).toInt(); -// -// QSpinBox *spinBox = static_cast(editor); -// spinBox->setValue(value); -//} -// -//void QmitkVisabilityDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, -// const QModelIndex &index) const -//{ -// QSpinBox *spinBox = static_cast(editor); -// spinBox->interpretText(); -// int value = spinBox->value(); -// -// model->setData(index, value, Qt::EditRole); -//} - -void QmitkVisibilityDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const -{ - editor->setGeometry(option.rect); -} - -void QmitkVisibilityDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - bool checkValue = index.data(Qt::DisplayRole).toBool(); - - QStyleOptionButton BtnStyle; - BtnStyle.state = QStyle::State_Enabled; - - if (checkValue) - { - BtnStyle.state |= QStyle::State_On; - } - else - { - BtnStyle.state |= QStyle::State_Off; - } - - BtnStyle.direction = QApplication::layoutDirection(); - BtnStyle.rect = CheckBoxRect(option); - QApplication::style()->drawControl(QStyle::CE_CheckBox, &BtnStyle, painter); -} - -bool QmitkVisibilityDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - Q_ASSERT(event); - Q_ASSERT(model); - - // make sure that the item is checkable - Qt::ItemFlags flags = model->flags(index); - if (!(flags & Qt::ItemIsEditable) || !(flags & Qt::ItemIsEnabled)) - { - return false; - } - - // make sure that we have the right event type - QMouseEvent* mouseEvent = dynamic_cast(event); - if (!mouseEvent) - { - return false; - } - else - { - if (mouseEvent->type() != QEvent::MouseButtonRelease || mouseEvent->button() != Qt::LeftButton) - { - return false; - } - } - - bool newState = !(index.data(Qt::EditRole).toBool()); - - return model->setData(index, QVariant(newState), Qt::EditRole); -} diff --git a/Modules/RenderWindowManager/src/mitkRenderWindowLayerController.cpp b/Modules/RenderWindowManager/src/mitkRenderWindowLayerController.cpp index bb1f56b6ab..2b22623526 100644 --- a/Modules/RenderWindowManager/src/mitkRenderWindowLayerController.cpp +++ b/Modules/RenderWindowManager/src/mitkRenderWindowLayerController.cpp @@ -1,521 +1,548 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkRenderWindowLayerController.h" -#include "mitkRenderingManager.h" +#include "mitkRenderWindowLayerUtilities.h" // mitk -#include -#include +#include "mitkRenderingManager.h" mitk::RenderWindowLayerController::RenderWindowLayerController() : m_DataStorage(nullptr) { - SetDataStorage(RenderingManager::GetInstance()->GetDataStorage()); - SetControlledRenderer(RenderingManager::GetInstance()->GetAllRegisteredRenderWindows()); -} - -mitk::RenderWindowLayerController::RenderWindowLayerController(std::shared_ptr renderWindowDataModel) - : m_RenderWindowDataModel(std::move(renderWindowDataModel)) - , m_DataStorage(nullptr) -{ - SetDataStorage(RenderingManager::GetInstance()->GetDataStorage()); SetControlledRenderer(RenderingManager::GetInstance()->GetAllRegisteredRenderWindows()); } mitk::RenderWindowLayerController::~RenderWindowLayerController() { + if (m_DataStorage.IsNull()) + { + return; + } + + // delete renderer properties for all data nodes + for (const auto& renderer : m_ControlledRenderer) + { + if (renderer.IsNotNull()) + { + // get all nodes connected with the renderer + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, true); + for (auto& layer : stackedLayers) + { + layer.second->GetPropertyList(renderer)->DeleteProperty("layer"); + layer.second->GetPropertyList(renderer)->DeleteProperty("fixedLayer"); + layer.second->GetPropertyList(renderer)->DeleteProperty("visible"); + layer.second->Modified(); + + // alternatively - but this will remove all renderer specific properties (not only the three above) + //layer.second->GetPropertyList(renderer)->Clear(); + } + } + } } void mitk::RenderWindowLayerController::SetDataStorage(DataStorage::Pointer dataStorage) { if (m_DataStorage != dataStorage) { // set the new data storage m_DataStorage = dataStorage; } - - // TODO: add listener? } -void mitk::RenderWindowLayerController::SetControlledRenderer(const mitk::RenderingManager::RenderWindowVector &renderWindows) +void mitk::RenderWindowLayerController::SetControlledRenderer(const RenderingManager::RenderWindowVector &renderWindows) { BaseRenderer* baseRenderer = nullptr; for (const auto &renderWindow : renderWindows) { baseRenderer = BaseRenderer::GetInstance(renderWindow); if (nullptr != baseRenderer) { m_ControlledRenderer.push_back(baseRenderer); } } } -void mitk::RenderWindowLayerController::SetControlledRenderer(RendererVector renderWindows) +void mitk::RenderWindowLayerController::SetControlledRenderer(RendererVector controlledRenderer) { - m_ControlledRenderer = renderWindows; + if (m_ControlledRenderer != controlledRenderer) + { + // set the new set of controlled renderer + m_ControlledRenderer = controlledRenderer; + } } -void mitk::RenderWindowLayerController::SetBaseDataNode(DataNode* dataNode, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::SetBaseDataNode(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { + if (nullptr == dataNode) + { + return; + } + if (nullptr == renderer) { // set the data node as base data node in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { SetBaseDataNode(dataNode, renderer); } } } else { // get the layer stack with the base data node of the current renderer - LayerStack stackedLayers = GetLayerStack(renderer, true); + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, true); if (!stackedLayers.empty()) { // see if base layer exists - LayerStack::iterator layerStackIterator = stackedLayers.find(0); + RenderWindowLayerUtilities::LayerStack::iterator layerStackIterator = stackedLayers.find(0); if (layerStackIterator != stackedLayers.end()) { // remove the current base data node from the current renderer + layerStackIterator->second->GetPropertyList(renderer)->DeleteProperty("layer"); layerStackIterator->second->SetBoolProperty("fixedLayer", false, renderer); layerStackIterator->second->SetVisibility(false, renderer); } } // 0 indicates the base data node --> set as new background dataNode->SetIntProperty("layer", 0, renderer); dataNode->SetBoolProperty("fixedLayer", true, renderer); dataNode->SetVisibility(true, renderer); + dataNode->Modified(); + mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } -void mitk::RenderWindowLayerController::InsertLayerNode(DataNode* dataNode, int layer /*= -1*/, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::InsertLayerNode(DataNode* dataNode, int layer /*= -1*/, const BaseRenderer* renderer /*= nullptr*/) { + if (nullptr == dataNode) + { + return; + } + if (nullptr == renderer) { // insert data node in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { InsertLayerNode(dataNode, layer, renderer); } } } else { if (0 == layer) { // 0 indicates the base data node --> set as new background (overwrite current base node if needed) SetBaseDataNode(dataNode, renderer); } else { InsertLayerNodeInternal(dataNode, layer, renderer); } - - mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } -void mitk::RenderWindowLayerController::InsertLayerNodeInternal(DataNode* dataNode, int newLayer, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::InsertLayerNodeInternal(DataNode* dataNode, int newLayer, const BaseRenderer* renderer /*= nullptr*/) { dataNode->SetBoolProperty("fixedLayer", true, renderer); dataNode->SetVisibility(true, renderer); // get the layer stack without the base node of the current renderer - LayerStack stackedLayers = GetLayerStack(renderer, false); + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (stackedLayers.empty()) { // no layer stack for the current renderer if (-1 == newLayer) { // set given layer as first layer above base layer (= 1) newLayer = 1; // alternatively: no layer stack for the current renderer -> insert as background node //SetBaseDataNode(dataNode, renderer); } } else { if (-1 == newLayer) { - // get the last value (highest int-key -> topmost layer) + // get the first value (highest int-key -> topmost layer) // +1 indicates inserting the node above the topmost layer - newLayer = stackedLayers.rbegin()->first + 1; + newLayer = stackedLayers.begin()->first + 1; } else { // see if layer is already taken - LayerStack::iterator layerStackIterator = stackedLayers.find(newLayer); + RenderWindowLayerUtilities::LayerStack::iterator layerStackIterator = stackedLayers.find(newLayer); for (; layerStackIterator != stackedLayers.end(); ++layerStackIterator) { // move data nodes after the new layer one layer up layerStackIterator->second->SetIntProperty("layer", layerStackIterator->first + 1, renderer); } } } // update data storage (the "data node model") dataNode->SetIntProperty("layer", newLayer, renderer); - // update render window data model (the "view model") - m_RenderWindowDataModel->InsertLayerNode(dataNode->GetName(), renderer->GetName()); + dataNode->Modified(); + mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } -void mitk::RenderWindowLayerController::RemoveLayerNode(int rowIndex, DataNode* dataNode, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::RemoveLayerNode(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { + if (nullptr == dataNode) + { + return; + } + if (nullptr == renderer) { // remove data node from all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { - // TODO: does not work here: rowIndex is different for different render window node lists - RemoveLayerNode(rowIndex, dataNode, renderer); + RemoveLayerNode(dataNode, renderer); } } } else { + // get the layer stack with the base node of the current renderer + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, true); + int layer = -1; + dataNode->GetIntProperty("layer", layer, renderer); + // get an index from iterator + int row = std::distance(stackedLayers.begin(), stackedLayers.find(layer)); + + // "remove" node from the renderer list + dataNode->GetPropertyList(renderer)->DeleteProperty("layer"); dataNode->SetBoolProperty("fixedLayer", false, renderer); dataNode->SetVisibility(false, renderer); - - m_RenderWindowDataModel->MoveNodeUp(rowIndex, dataNode->GetName(), renderer->GetName()); - + dataNode->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } - -bool mitk::RenderWindowLayerController::MoveNodeToFront(DataNode* dataNode, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::MoveNodeToFront(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { + if (nullptr == dataNode) + { + return; + } + if (nullptr == renderer) { // move data node to front in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { MoveNodeToFront(dataNode, renderer); } } } else { // get the layer stack without the base node of the current renderer - LayerStack stackedLayers = GetLayerStack(renderer, false); + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (!stackedLayers.empty()) { - // get the last value (highest int-key -> topmost layer) - int topmostLayer = stackedLayers.rbegin()->first; + // get the first value (highest int-key -> topmost layer) + int topmostLayer = stackedLayers.begin()->first; // get the current layer value of the given data node int currentLayer; bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer); if (wasFound && currentLayer < topmostLayer) { // move the current data node to the current topmost layer dataNode->SetIntProperty("layer", topmostLayer, renderer); for (auto& layer : stackedLayers) { if (layer.second != dataNode && layer.first > currentLayer) { // move all other data nodes one layer down, if their layer was above the layer of the current node layer.second->SetIntProperty("layer", layer.first - 1, renderer); // alternatively: stack all layers below the topmost layer // this would fill gaps between the layers of the renderer, every time a node is moved to front // TODO: reverse iteration needed! layer.second->SetIntProperty("layer", --topmostLayer, renderer); - return true; } // else: current data node has already been moved to the topmost layer } } // else: data node has no layer information or is already the topmost layer node } // else: do not work with empty layer stack } - return false; } -bool mitk::RenderWindowLayerController::MoveNodeToBack(DataNode* dataNode, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::MoveNodeToBack(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { + if (nullptr == dataNode) + { + return; + } + if (nullptr == renderer) { // move data node to back in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { MoveNodeToBack(dataNode, renderer); } } } else { // get the layer stack without the base node of the current renderer - LayerStack stackedLayers = GetLayerStack(renderer, false); + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (!stackedLayers.empty()) { - // get the first value (lowest int-key) + // get the last value (lowest int-key) // cannot be the layer 0 (base node) as the base node was excluded by the 'GetLayerStack'-function - int lowermostLayer = stackedLayers.begin()->first; + int lowermostLayer = stackedLayers.rbegin()->first; // get the current layer value of the given data node int currentLayer; bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer); if (wasFound && currentLayer > lowermostLayer) { // move the current data node to the current lowermost layer dataNode->SetIntProperty("layer", lowermostLayer, renderer); // move all other data nodes one layer up for (auto& layer : stackedLayers) { if (layer.second != dataNode) { layer.second->SetIntProperty("layer", layer.first + 1, renderer); // alternatively: stack all layers on top of the lowermost layer // this would fill gaps between the layers of the renderer, every time a node is moved to back //layer.second->SetIntProperty("layer", ++lowermostLayer, renderer); - return true; } // else: current data node has already been moved to the lowermost layer } } // else: data node has no layer information or is already the lowermost layer node } // else: do not work with empty layer stack } - return false; } -bool mitk::RenderWindowLayerController::MoveNodeUp(int rowIndex, DataNode* dataNode, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::MoveNodeUp(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { + if (nullptr == dataNode) + { + return; + } + if (nullptr == renderer) { // move data node down in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { - // TODO: does not work here: rowIndex is different for different render window node lists - MoveNodeUp(rowIndex, dataNode, renderer); + MoveNodeUp(dataNode, renderer); } } } else { // get the layer stack without the base node of the current renderer - LayerStack stackedLayers = GetLayerStack(renderer, false); + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (!stackedLayers.empty()) { - // get the last value (highest int-key -> topmost layer) - int topmostLayer = stackedLayers.rbegin()->first; // get the current layer value of the given data node int currentLayer; bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer); - if (wasFound && currentLayer < topmostLayer) + if (wasFound) { - // current node is not on the topmost layer and therefore can be moved one layer up - // swap the layers of the dataNode and the dataNode on the next higher layer - LayerStack::iterator layerStackIterator = stackedLayers.find(currentLayer); - ++layerStackIterator; - DataNode::Pointer higherDataNode = layerStackIterator->second; - dataNode->SetIntProperty("layer", layerStackIterator->first, renderer); - higherDataNode->SetIntProperty("layer", currentLayer, renderer); - - m_RenderWindowDataModel->MoveNodeUp(rowIndex, dataNode->GetName(), renderer->GetName()); - - mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); - return true; + // get the current layer in the map of stacked layers + RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIterator = stackedLayers.find(currentLayer); + if (layerStackIterator != stackedLayers.end() && layerStackIterator != stackedLayers.begin()) + { + // found the element in the map, at different position than 'begin' -> + // current node is not on the topmost layer and therefore can be moved one layer up + // swap the layers of the dataNode and the dataNode on the next higher layer (previous map element) + RenderWindowLayerUtilities::LayerStack::const_iterator prevLayerStackIterator = std::prev(layerStackIterator); + dataNode->SetIntProperty("layer", prevLayerStackIterator->first, renderer); + prevLayerStackIterator->second->SetIntProperty("layer", currentLayer, renderer); + //prevLayerStackIterator->second->Modified(); + dataNode->Modified(); + mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); + } + // else: layer stack does not contain a layer with the 'currentLayer'data node or + // layer is already the topmost layer node } - // else: data node has no layer information or is already the topmost layer node + // else: data node has no layer information } // else: do not work with empty layer stack } - return false; } -bool mitk::RenderWindowLayerController::MoveNodeDown(int rowIndex, DataNode* dataNode, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::MoveNodeDown(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { + if (nullptr == dataNode) + { + return; + } + if (nullptr == renderer) { // move data node up in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { - // TODO: does not work here: rowIndex is different for different render window node lists - MoveNodeDown(rowIndex, dataNode, renderer); + MoveNodeDown(dataNode, renderer); } } } else { // get the layer stack without the base node of the current renderer - LayerStack stackedLayers = GetLayerStack(renderer, false); + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (!stackedLayers.empty()) { - // get the first value (lowest int-key) - // cannot be the layer 0 (base node) as the base node was excluded by the 'GetLayerStack'-function - int lowermostLayer = stackedLayers.begin()->first; // get the current layer value of the given data node int currentLayer; bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer); - if (wasFound && currentLayer > lowermostLayer) + if (wasFound) { - // current node is not on the lowermost layer and therefore can be moved one layer down - // swap the layers of the dataNode and the dataNode on the next lower layer - LayerStack::iterator layerStackIterator = stackedLayers.find(currentLayer); - --layerStackIterator; - DataNode::Pointer lowerDataNode = layerStackIterator->second; - dataNode->SetIntProperty("layer", layerStackIterator->first, renderer); - lowerDataNode->SetIntProperty("layer", currentLayer, renderer); - - m_RenderWindowDataModel->MoveNodeDown(rowIndex, dataNode->GetName(), renderer->GetName()); - - mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); - return true; + // get the current layer in the map of stacked layers + RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIterator = stackedLayers.find(currentLayer); + if (layerStackIterator != stackedLayers.end()) + { + // found the element in the map ... + RenderWindowLayerUtilities::LayerStack::const_iterator nextLayerStackIterator = std::next(layerStackIterator); + if (nextLayerStackIterator != stackedLayers.end()) + { + // ... and found a successor -> + // current node is not on the lowermost layer and therefore can be moved one layer down + // swap the layers of the dataNode and the dataNode on the next lower layer (next map element) + dataNode->SetIntProperty("layer", nextLayerStackIterator->first, renderer); + nextLayerStackIterator->second->SetIntProperty("layer", currentLayer, renderer); + //nextLayerStackIterator->second->Modified(); + dataNode->Modified(); + mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); + } + // else: data node is already the lowermost layer node + } + // else: layer stack does not contain a layer with the 'currentLayer' } - // else: data node has no layer information or is already the lowermost layer node + // else: data node has no layer information } // else: do not work with empty layer stack } - return false; } -void mitk::RenderWindowLayerController::SetVisibilityOfDataNode(bool visibility, DataNode* dataNode, const mitk::BaseRenderer* renderer /*=nullptr*/) +void mitk::RenderWindowLayerController::SetVisibilityOfDataNode(bool visibility, DataNode* dataNode, const BaseRenderer* renderer /*=nullptr*/) { + if (nullptr == dataNode) + { + return; + } + if (nullptr == renderer) { // set visibility of data node in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { - //SetVisibilityOfDataNode(visibility, dataNode, renderer); dataNode->SetVisibility(visibility, renderer); + dataNode->Modified(); + mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } } else { dataNode->SetVisibility(visibility, renderer); + dataNode->Modified(); + mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } void mitk::RenderWindowLayerController::HideDataNodeInAllRenderer(const DataNode* dataNode) { for (const auto& renderer : m_ControlledRenderer) { - if (renderer.IsNotNull()) + if (nullptr != dataNode && renderer.IsNotNull()) { - dataNode->GetPropertyList(renderer)->SetBoolProperty("fixedLayer", false); dataNode->GetPropertyList(renderer)->SetBoolProperty("visible", false); } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } -void mitk::RenderWindowLayerController::ResetRenderer(bool onlyVisibility /*= true*/, const mitk::BaseRenderer* renderer /*= nullptr*/) +void mitk::RenderWindowLayerController::ResetRenderer(bool onlyVisibility /*= true*/, const BaseRenderer* renderer /*= nullptr*/) { if (nullptr == renderer) { // reset all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { ResetRenderer(onlyVisibility, renderer); } } } else { // get the layer stack with the base node of the current renderer - LayerStack stackedLayers = GetLayerStack(renderer, true); + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, true); if (!stackedLayers.empty()) { for (const auto& layer : stackedLayers) { int layerLevel; layer.second->GetIntProperty("layer", layerLevel, renderer); if (0 == layerLevel) { // set base data node visibility to true (layer = 0) layer.second->SetVisibility(true, renderer); } else { // modify layer node if (onlyVisibility) { // set layer node visibility to false layer.second->SetVisibility(false, renderer); } else { - // remove layer node from current renderer + layer.second->GetPropertyList(renderer)->DeleteProperty("layer"); layer.second->SetBoolProperty("fixedLayer", false, renderer); layer.second->SetVisibility(false, renderer); } } + layer.second->Modified(); } - } - } -} -mitk::RenderWindowLayerController::LayerStack mitk::RenderWindowLayerController::GetLayerStack(const mitk::BaseRenderer* renderer, bool withBaseNode) -{ - LayerStack stackedLayers; - if (m_DataStorage.IsNull() || renderer == nullptr) - { - // no nodes to stack or no renderer selected - return stackedLayers; - } - - // see 'QmitkStdMultiWidgetEditor::CreateQtPartControl' for id of GetQmitkRenderWindow - //m_Renderer = this->GetRenderWindowPart()->GetQmitkRenderWindow("axial" /*"sagittal"*/ /*coronal*/)->GetRenderer(); - int layer = -1; - mitk::NodePredicateProperty::Pointer helperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)); - mitk::NodePredicateNot::Pointer notAHelperObject = mitk::NodePredicateNot::New(helperObject); - mitk::DataStorage::SetOfObjects::ConstPointer filteredDataNodes = m_DataStorage->GetSubset(notAHelperObject); - - for (DataStorage::SetOfObjects::ConstIterator it = filteredDataNodes->Begin(); it != filteredDataNodes->End(); ++it) - { - DataNode::Pointer dataNode = it->Value(); - if (dataNode.IsNull()) - { - continue; - } - - bool fixedLayer = false; - dataNode->GetBoolProperty("fixedLayer", fixedLayer, renderer); - bool layerFound = dataNode->GetIntProperty("layer", layer, renderer); - if (fixedLayer && layerFound) - { - if (layer != 0 || withBaseNode) - { - // data node is not on the base layer or the base layer should be included anyway - stackedLayers.insert(std::make_pair(layer, dataNode)); - } + mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } - return stackedLayers; } diff --git a/Modules/RenderWindowManager/src/mitkRenderWindowLayerUtilities.cpp b/Modules/RenderWindowManager/src/mitkRenderWindowLayerUtilities.cpp new file mode 100644 index 0000000000..253113cc08 --- /dev/null +++ b/Modules/RenderWindowManager/src/mitkRenderWindowLayerUtilities.cpp @@ -0,0 +1,62 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkRenderWindowLayerUtilities.h" + +// mitk +#include +#include +#include + +RenderWindowLayerUtilities::LayerStack RenderWindowLayerUtilities::GetLayerStack(const mitk::DataStorage* dataStorage, const mitk::BaseRenderer* renderer, bool withBaseNode) +{ + LayerStack stackedLayers; + if (nullptr == dataStorage || nullptr == renderer) + { + // no nodes to stack or no renderer selected + return stackedLayers; + } + + int layer = -1; + mitk::NodePredicateProperty::Pointer helperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)); + mitk::NodePredicateNot::Pointer notAHelperObject = mitk::NodePredicateNot::New(helperObject); + + mitk::NodePredicateProperty::Pointer fixedLayer = mitk::NodePredicateProperty::New("fixedLayer", mitk::BoolProperty::New(true), renderer); + + // combine node predicates + mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(notAHelperObject, fixedLayer); + mitk::DataStorage::SetOfObjects::ConstPointer filteredDataNodes = dataStorage->GetSubset(combinedNodePredicate); + + for (mitk::DataStorage::SetOfObjects::ConstIterator it = filteredDataNodes->Begin(); it != filteredDataNodes->End(); ++it) + { + mitk::DataNode::Pointer dataNode = it->Value(); + if (dataNode.IsNull()) + { + continue; + } + + bool layerFound = dataNode->GetIntProperty("layer", layer, renderer); + if (layerFound) + { + if (layer != 0 || withBaseNode) + { + // data node is not on the base layer or the base layer should be included anyway + stackedLayers.insert(std::make_pair(layer, dataNode)); + } + } + } + return stackedLayers; +} diff --git a/Modules/RenderWindowManager/src/mitkRenderWindowViewDirectionController.cpp b/Modules/RenderWindowManager/src/mitkRenderWindowViewDirectionController.cpp new file mode 100644 index 0000000000..8a5ef4495f --- /dev/null +++ b/Modules/RenderWindowManager/src/mitkRenderWindowViewDirectionController.cpp @@ -0,0 +1,130 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkRenderWindowViewDirectionController.h" +#include "mitkRenderWindowLayerUtilities.h" + +// mitk +#include +#include +#include +#include + +mitk::RenderWindowViewDirectionController::RenderWindowViewDirectionController() + : m_DataStorage(nullptr) +{ + SetControlledRenderer(RenderingManager::GetInstance()->GetAllRegisteredRenderWindows()); +} + +mitk::RenderWindowViewDirectionController::~RenderWindowViewDirectionController() +{ + // nothing here +} + +void mitk::RenderWindowViewDirectionController::SetDataStorage(DataStorage::Pointer dataStorage) +{ + if (m_DataStorage != dataStorage) + { + // set the new data storage + m_DataStorage = dataStorage; + } +} + +void mitk::RenderWindowViewDirectionController::SetControlledRenderer(const RenderingManager::RenderWindowVector &renderWindows) +{ + BaseRenderer* baseRenderer = nullptr; + for (const auto &renderWindow : renderWindows) + { + baseRenderer = BaseRenderer::GetInstance(renderWindow); + if (nullptr != baseRenderer) + { + m_ControlledRenderer.push_back(baseRenderer); + } + } +} + +void mitk::RenderWindowViewDirectionController::SetControlledRenderer(RendererVector controlledRenderer) +{ + if (m_ControlledRenderer != controlledRenderer) + { + // set the new set of controlled renderer + m_ControlledRenderer = controlledRenderer; + } +} + +void mitk::RenderWindowViewDirectionController::SetViewDirectionOfRenderer(const std::string &viewDirection, BaseRenderer* renderer /*=nullptr*/) +{ + if (nullptr == renderer) + { + + // set visibility of data node in all controlled renderer + for (auto& renderer : m_ControlledRenderer) + { + if (renderer.IsNotNull()) + { + SetViewDirectionOfRenderer(viewDirection, renderer); + } + } + } + else + { + mitk::SliceNavigationController* sliceNavigationController = renderer->GetSliceNavigationController(); + if ("axial" == viewDirection) + { + sliceNavigationController->SetDefaultViewDirection(mitk::SliceNavigationController::Axial); + } + else if ("coronal" == viewDirection) + { + sliceNavigationController->SetDefaultViewDirection(mitk::SliceNavigationController::Frontal); + } + else if ("sagittal" == viewDirection) + { + sliceNavigationController->SetDefaultViewDirection(mitk::SliceNavigationController::Sagittal); + } + + // initialize the views to the bounding geometry + InitializeViewByBoundingObjects(renderer); + } +} + +void mitk::RenderWindowViewDirectionController::InitializeViewByBoundingObjects(const BaseRenderer* renderer) +{ + if (nullptr == m_DataStorage || nullptr == renderer) + { + return; + } + + // get all nodes that have not set "includeInBoundingBox" to false + mitk::NodePredicateProperty::Pointer includeInBoundingBox = mitk::NodePredicateProperty::New("includeInBoundingBox", mitk::BoolProperty::New(false)); + mitk::NodePredicateNot::Pointer notIncludeInBoundingBox = mitk::NodePredicateNot::New(includeInBoundingBox); + + // get all non-helper objects + mitk::NodePredicateProperty::Pointer helperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)); + mitk::NodePredicateNot::Pointer notAHelperObject = mitk::NodePredicateNot::New(helperObject); + + // get all nodes that have a fixed layer for the given renderer + mitk::NodePredicateProperty::Pointer fixedLayer = mitk::NodePredicateProperty::New("fixedLayer", mitk::BoolProperty::New(true), renderer); + + // combine node predicates + mitk::NodePredicateAnd::Pointer combinedNodePredicate = mitk::NodePredicateAnd::New(notIncludeInBoundingBox, notAHelperObject, fixedLayer); + mitk::DataStorage::SetOfObjects::ConstPointer filteredDataNodes = m_DataStorage->GetSubset(combinedNodePredicate); + + // calculate bounding geometry of these nodes + mitk::TimeGeometry::Pointer bounds = m_DataStorage->ComputeBoundingGeometry3D(filteredDataNodes, "visible", renderer); + + // initialize the views to the bounding geometry + mitk::RenderingManager::GetInstance()->InitializeView(renderer->GetRenderWindow(), bounds); +} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/files.cmake b/Plugins/org.mitk.gui.qt.renderwindowmanager/files.cmake index 54e3d0e4ba..1bd24a4c92 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/files.cmake +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/files.cmake @@ -1,29 +1,29 @@ set(INTERNAL_CPP_FILES mitkPluginActivator.cpp QmitkRenderWindowManagerView.cpp - QmitkLayerManagerAddNodeWidget.cpp + QmitkLayerManagerAddLayerWidget.cpp ) set(UI_FILES src/internal/QmitkRenderWindowManagerControls.ui - src/internal/QmitkLayerManagerAddNodeControls.ui + src/internal/QmitkLayerManagerAddLayerControls.ui ) set(MOC_H_FILES src/internal/mitkPluginActivator.h src/internal/QmitkRenderWindowManagerView.h - src/internal/QmitkLayerManagerAddNodeWidget.h + src/internal/QmitkLayerManagerAddLayerWidget.h ) set(CACHED_RESOURCE_FILES resources/LayerManager_48.png plugin.xml ) set(QRC_FILES resources/renderwindowmanager.qrc ) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeControls.ui b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerControls.ui similarity index 79% rename from Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeControls.ui rename to Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerControls.ui index 0f5a62e698..5581caaa10 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeControls.ui +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerControls.ui @@ -1,70 +1,71 @@ - QmitkLayerManagerAddNodeControls - + QmitkLayerManagerAddLayerControls + 0 0 459 844 0 0 0 0 - QmitkLayerManagerAddNode + QmitkLayerManagerAddLayer 0 0 - Add data node + Add layer - - + + 0 0 0 0 - + - Add node to renderer + Add layer to renderer + diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeWidget.cpp b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerWidget.cpp similarity index 55% rename from Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeWidget.cpp rename to Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerWidget.cpp index 21c020c729..7964ad6683 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeWidget.cpp +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerWidget.cpp @@ -1,94 +1,93 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#include "QmitkLayerManagerAddNodeWidget.h" +#include "QmitkLayerManagerAddLayerWidget.h" #include #include -const QString QmitkLayerManagerAddNodeWidget::VIEW_ID = "org.mitk.Widgets.QmitkLayerManagerAddNode"; +const QString QmitkLayerManagerAddLayerWidget::VIEW_ID = "org.mitk.Widgets.QmitkLayerManagerAddLayer"; -QmitkLayerManagerAddNodeWidget::QmitkLayerManagerAddNodeWidget(QWidget* parent /*= nullptr*/) +QmitkLayerManagerAddLayerWidget::QmitkLayerManagerAddLayerWidget(QWidget* parent /*= nullptr*/) : QWidget(parent, Qt::Window) , m_DataStorage(nullptr) { Init(); } -QmitkLayerManagerAddNodeWidget::~QmitkLayerManagerAddNodeWidget() +QmitkLayerManagerAddLayerWidget::~QmitkLayerManagerAddLayerWidget() { // nothing here } -void QmitkLayerManagerAddNodeWidget::Init() +void QmitkLayerManagerAddLayerWidget::Init() { m_Controls.setupUi(this); - m_DataNodeListModel = new QStringListModel(this); - m_Controls.listViewDataNodes->setModel(m_DataNodeListModel); - m_Controls.listViewDataNodes->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_LayerListModel = new QStringListModel(this); + m_Controls.listViewLayers->setModel(m_LayerListModel); + m_Controls.listViewLayers->setEditTriggers(QAbstractItemView::NoEditTriggers); - connect(m_Controls.pushButtonAddDataNode, SIGNAL(clicked()), this, SLOT(AddDataNodeToRenderer())); - connect(m_Controls.pushButtonAddDataNode, SIGNAL(clicked()), this, SLOT(hide())); + connect(m_Controls.pushButtonAddLayer, SIGNAL(clicked()), this, SLOT(AddLayerToRenderer())); + connect(m_Controls.pushButtonAddLayer, SIGNAL(clicked()), this, SLOT(hide())); - m_Controls.pushButtonAddDataNode->setEnabled(false); + m_Controls.pushButtonAddLayer->setEnabled(false); } -void QmitkLayerManagerAddNodeWidget::SetDataStorage(mitk::DataStorage::Pointer dataStorage) +void QmitkLayerManagerAddLayerWidget::SetDataStorage(mitk::DataStorage::Pointer dataStorage) { m_DataStorage = dataStorage; } -void QmitkLayerManagerAddNodeWidget::ListDataNodes() +void QmitkLayerManagerAddLayerWidget::ListLayer() { if (m_DataStorage.IsNotNull()) { // get the data nodes from the data storage that are not helper objects mitk::NodePredicateProperty::Pointer helperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer notAHelperObject = mitk::NodePredicateNot::New(helperObject); mitk::DataStorage::SetOfObjects::ConstPointer filteredDataNodes = m_DataStorage->GetSubset(notAHelperObject); QStringList stringList; for (mitk::DataStorage::SetOfObjects::ConstIterator it = filteredDataNodes->Begin(); it != filteredDataNodes->End(); ++it) { stringList << QString::fromStdString(it->Value()->GetName()); } - m_DataNodeListModel->setStringList(stringList); + m_LayerListModel->setStringList(stringList); if (stringList.isEmpty()) { - m_Controls.pushButtonAddDataNode->setEnabled(false); + m_Controls.pushButtonAddLayer->setEnabled(false); } else { - m_Controls.pushButtonAddDataNode->setEnabled(true); + m_Controls.pushButtonAddLayer->setEnabled(true); } } } -void QmitkLayerManagerAddNodeWidget::AddDataNodeToRenderer() +void QmitkLayerManagerAddLayerWidget::AddLayerToRenderer() { - QModelIndex selectedIndex = m_Controls.listViewDataNodes->currentIndex(); + QModelIndex selectedIndex = m_Controls.listViewLayers->currentIndex(); if (selectedIndex.isValid()) { int listRow = selectedIndex.row(); - QString dataNodeName = m_DataNodeListModel->stringList().at(listRow); - + QString dataNodeName = m_LayerListModel->stringList().at(listRow); mitk::DataNode* dataNode = m_DataStorage->GetNamedNode(dataNodeName.toStdString()); - emit NodeToAddSelected(dataNode); + emit LayerToAddSelected(dataNode); } } diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeWidget.h b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerWidget.h similarity index 62% rename from Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeWidget.h rename to Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerWidget.h index 890dbd2a57..3e1e6bdcdd 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddNodeWidget.h +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkLayerManagerAddLayerWidget.h @@ -1,70 +1,68 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ -#ifndef QMITKLAYERMANAGERADDNODEWIDGET_H -#define QMITKLAYERMANAGERADDNODEWIDGET_H +#ifndef QMITKLAYERMANAGERADDLAYERWIDGET_H +#define QMITKLAYERMANAGERADDLAYERWIDGET_H -#include "ui_QmitkLayerManagerAddNodeControls.h" +#include "ui_QmitkLayerManagerAddLayerControls.h" // mitk #include // Qt includes #include #include #include /** * @brief * */ -class QmitkLayerManagerAddNodeWidget : public QWidget +class QmitkLayerManagerAddLayerWidget : public QWidget { Q_OBJECT public: static const QString VIEW_ID; - QmitkLayerManagerAddNodeWidget(QWidget* parent = nullptr); - ~QmitkLayerManagerAddNodeWidget(); + QmitkLayerManagerAddLayerWidget(QWidget* parent = nullptr); + ~QmitkLayerManagerAddLayerWidget(); /** * @brief set the data storage of the tree model * * @param[in] dataStorage the mitk::DataStorage that should be used */ void SetDataStorage(mitk::DataStorage::Pointer dataStorage); - void ListDataNodes(); + void ListLayer(); public Q_SLOTS: - void AddDataNodeToRenderer(); + void AddLayerToRenderer(); Q_SIGNALS: - void NodeToAddSelected(mitk::DataNode* dataNode); + void LayerToAddSelected(mitk::DataNode* dataNode); private: void Init(); - Ui::QmitkLayerManagerAddNodeControls m_Controls; + Ui::QmitkLayerManagerAddLayerControls m_Controls; - QStringListModel* m_DataNodeListModel; + QStringListModel* m_LayerListModel; mitk::DataStorage::Pointer m_DataStorage; - - // TODO: map for nodename (to display) and sopinstanceuid for identifying a data node }; -#endif // QMITKLAYERMANAGERADDNODEWIDGET_H +#endif // QMITKLAYERMANAGERADDLAYERWIDGET_H diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerControls.ui b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerControls.ui index 00d440a164..f925772063 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerControls.ui +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerControls.ui @@ -1,105 +1,122 @@ QmitkRenderWindowManagerControls 0 0 - 263 - 227 + 386 + 572 0 0 QmitkRenderWindowManager -1 Render window overview Move up - - + + - Move down + Axial + + + true - - + + - Add Node + Coronal + + + + + + + Sagittal - + - Remove Node + Move down - - + + + + Remove layer + + + + + - Set as Base + Add Layer - + - Axial + Set as base layer - - + + - Coronal + Reset render window - - + + - Sagittal + Clear render window diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp index 15bf448696..54bb939604 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp @@ -1,164 +1,218 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // render window manager plugin #include "QmitkRenderWindowManagerView.h" // blueberry #include #include // mitk #include // qt #include #include #include const std::string QmitkRenderWindowManagerView::VIEW_ID = "org.mitk.views.renderwindowmanager"; void QmitkRenderWindowManagerView::SetFocus() { m_Controls.radioButtonAxial->setFocus(); } void QmitkRenderWindowManagerView::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Parent = parent; m_Controls.setupUi(m_Parent); - // initialize the render window layer controller and set the controller renderer (in constructor) and the data storage - m_RenderWindowLayerController = new mitk::RenderWindowLayerController(); + // initialize the render window layer controller and the render window view direction controller + // and set the controller renderer (in constructor) and the data storage + m_RenderWindowLayerController = std::make_unique(); + m_RenderWindowViewDirectionController = std::make_unique(); m_RenderWindowLayerController->SetDataStorage(GetDataStorage()); + m_RenderWindowViewDirectionController->SetDataStorage(GetDataStorage()); mitk::RenderWindowLayerController::RendererVector controlledRenderer = m_RenderWindowLayerController->GetControlledRenderer(); for (const auto& renderer : controlledRenderer) { m_Controls.comboBoxRenderWindowSelection->addItem(renderer->GetName()); } - m_CurrentRendererName = m_Controls.comboBoxRenderWindowSelection->itemText(0); - // create a new model - m_RenderWindowModel.insert(m_CurrentRendererName, new QmitkRenderWindowDataModel(this)); - m_Controls.renderWindowTableView->setModel(m_RenderWindowModel.value(m_CurrentRendererName)); + m_RenderWindowDataModel = std::make_unique(this); + m_RenderWindowDataModel->SetDataStorage(GetDataStorage()); + m_RenderWindowDataModel->SetCurrentRenderer(m_Controls.comboBoxRenderWindowSelection->itemText(0).toStdString()); + + m_Controls.renderWindowTableView->setModel(m_RenderWindowDataModel.get()); m_Controls.renderWindowTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); m_Controls.renderWindowTableView->horizontalHeader()->setStretchLastSection(true); - - m_RenderWindowModel.value(m_CurrentRendererName)->SetDataStorage(GetDataStorage()); //m_VisibilityDelegate = new QmitkVisibilityDelegate(this); //m_Controls.renderWindowTableView->setItemDelegateForColumn(0, m_VisibilityDelegate); - mitk::BaseRenderer* renderer = mitk::BaseRenderer::GetByName(m_CurrentRendererName.toStdString()); - mitk::RenderWindowLayerController::LayerStack layerStack = m_RenderWindowLayerController->GetLayerStack(renderer, true); - m_RenderWindowModel.value(m_CurrentRendererName)->UpdateTableForRenderWindow(layerStack); - - m_Controls.radioButtonAxial->setChecked(true); - - m_AddDataNodeWidget = new QmitkLayerManagerAddNodeWidget(m_Parent); - m_AddDataNodeWidget->hide(); - m_AddDataNodeWidget->SetDataStorage(GetDataStorage()); + m_AddLayerWidget = new QmitkLayerManagerAddLayerWidget(m_Parent); + m_AddLayerWidget->hide(); + m_AddLayerWidget->SetDataStorage(GetDataStorage()); SetUpConnections(); } void QmitkRenderWindowManagerView::SetUpConnections(void) { connect(m_Controls.comboBoxRenderWindowSelection, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnRenderWindowSelectionChanged(const QString&))); + connect(m_Controls.pushButtonAddLayer, SIGNAL(clicked()), this, SLOT(ShowAddLayerWidget())); + connect(m_Controls.pushButtonRemoveLayer, SIGNAL(clicked()), this, SLOT(RemoveLayer())); + connect(m_Controls.pushButtonSetAsBaseLayer, SIGNAL(clicked()), this, SLOT(SetAsBaseLayer())); + QSignalMapper* udSignalMapper = new QSignalMapper(this); udSignalMapper->setMapping(m_Controls.pushButtonMoveUp, QString("up")); udSignalMapper->setMapping(m_Controls.pushButtonMoveDown, QString("down")); - + connect(udSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(MoveLayer(const QString&))); connect(m_Controls.pushButtonMoveUp, SIGNAL(clicked()), udSignalMapper, SLOT(map())); connect(m_Controls.pushButtonMoveDown, SIGNAL(clicked()), udSignalMapper, SLOT(map())); - connect(udSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(MoveDataNode(const QString&))); - connect(m_Controls.pushButtonAddNode, SIGNAL(clicked()), this, SLOT(ShowAddDataNodeWidget())); - connect(m_Controls.pushButtonRemoveNode, SIGNAL(clicked()), this, SLOT(RemoveDataNode())); - connect(m_Controls.pushButtonSetAsBaseNode, SIGNAL(clicked()), this, SLOT(SetAsBaseDataNode())); + connect(m_Controls.pushButtonResetRenderer, SIGNAL(clicked()), this, SLOT(ResetRenderer())); + connect(m_Controls.pushButtonClearRenderer, SIGNAL(clicked()), this, SLOT(ClearRenderer())); - //connect(m_Controls.radioButtonAxial, SIGNAL(clicked()), this, SLOT(DoImageProcessing())); - //connect(m_Controls.radioButtonCoronal, SIGNAL(clicked()), this, SLOT(DoImageProcessing())); - //connect(m_Controls.radioButtonSagittal, SIGNAL(clicked()), this, SLOT(DoImageProcessing())); + QSignalMapper* changeViewDirectionSignalMapper = new QSignalMapper(this); + changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonAxial, QString("axial")); + changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonCoronal, QString("coronal")); + changeViewDirectionSignalMapper->setMapping(m_Controls.radioButtonSagittal, QString("sagittal")); + connect(changeViewDirectionSignalMapper, SIGNAL(mapped(const QString&)), this, SLOT(ChangeViewDirection(const QString&))); + connect(m_Controls.radioButtonAxial, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); + connect(m_Controls.radioButtonCoronal, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); + connect(m_Controls.radioButtonSagittal, SIGNAL(clicked()), changeViewDirectionSignalMapper, SLOT(map())); - connect(m_AddDataNodeWidget, SIGNAL(NodeToAddSelected(mitk::DataNode*)), this, SLOT(AddDataNode(mitk::DataNode*))); + connect(m_AddLayerWidget, SIGNAL(LayerToAddSelected(mitk::DataNode*)), this, SLOT(AddLayer(mitk::DataNode*))); } void QmitkRenderWindowManagerView::OnRenderWindowSelectionChanged(const QString &renderWindowId) { - m_CurrentRendererName = renderWindowId; - if (!m_RenderWindowModel.contains(m_CurrentRendererName)) + std::string currentRendererName = renderWindowId.toStdString(); + m_RenderWindowDataModel->SetCurrentRenderer(currentRendererName); + + mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(currentRendererName); + mitk::SliceNavigationController::ViewDirection viewDirection = selectedRenderer->GetSliceNavigationController()->GetDefaultViewDirection(); + switch (viewDirection) { - m_RenderWindowModel.insert(m_CurrentRendererName, new QmitkRenderWindowDataModel(this)); - m_RenderWindowModel.value(m_CurrentRendererName)->SetDataStorage(GetDataStorage()); + case mitk::SliceNavigationController::Axial: + m_Controls.radioButtonAxial->setChecked(true); + break; + case mitk::SliceNavigationController::Frontal: + m_Controls.radioButtonCoronal->setChecked(true); + break; + case mitk::SliceNavigationController::Sagittal: + m_Controls.radioButtonSagittal->setChecked(true); + break; + default: + break; } - - m_Controls.renderWindowTableView->setModel(m_RenderWindowModel.value(m_CurrentRendererName)); - - mitk::BaseRenderer* renderer = mitk::BaseRenderer::GetByName(m_CurrentRendererName.toStdString()); - mitk::RenderWindowLayerController::LayerStack layerStack = m_RenderWindowLayerController->GetLayerStack(renderer, true); - - m_RenderWindowModel.value(m_CurrentRendererName)->UpdateTableForRenderWindow(layerStack); } -void QmitkRenderWindowManagerView::ShowAddDataNodeWidget() +void QmitkRenderWindowManagerView::ShowAddLayerWidget() { - m_AddDataNodeWidget->ListDataNodes(); - m_AddDataNodeWidget->show(); + m_AddLayerWidget->ListLayer(); + m_AddLayerWidget->show(); } -void QmitkRenderWindowManagerView::AddDataNode(mitk::DataNode* dataNode) +void QmitkRenderWindowManagerView::AddLayer(mitk::DataNode* dataNode) { - mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_CurrentRendererName.toStdString()); + const mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_Controls.comboBoxRenderWindowSelection->currentText().toStdString()); m_RenderWindowLayerController->InsertLayerNode(dataNode, -1, selectedRenderer); - - m_RenderWindowModel.value(m_CurrentRendererName)->UpdateTableForRenderWindow(m_RenderWindowLayerController->GetLayerStack(selectedRenderer, true)); } -void QmitkRenderWindowManagerView::RemoveDataNode() +void QmitkRenderWindowManagerView::RemoveLayer() { - // TODO: not yet implemented + QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); + if (selectedIndex.isValid()) + { + QVariant rowData = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); + mitk::DataNode* dataNode = GetDataStorage()->GetNamedNode(rowData.toString().toStdString()); + const mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_Controls.comboBoxRenderWindowSelection->currentText().toStdString()); + + m_RenderWindowLayerController->RemoveLayerNode(dataNode, selectedRenderer); + m_Controls.renderWindowTableView->clearSelection(); + } } -void QmitkRenderWindowManagerView::SetAsBaseDataNode() +void QmitkRenderWindowManagerView::SetAsBaseLayer() { - // TODO: not yet implemented + QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); + if (selectedIndex.isValid()) + { + QVariant rowData = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); + mitk::DataNode* dataNode = GetDataStorage()->GetNamedNode(rowData.toString().toStdString()); + const mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_Controls.comboBoxRenderWindowSelection->currentText().toStdString()); + + m_RenderWindowLayerController->SetBaseDataNode(dataNode, selectedRenderer); + m_Controls.renderWindowTableView->clearSelection(); + } } -void QmitkRenderWindowManagerView::MoveDataNode(const QString &direction) +void QmitkRenderWindowManagerView::MoveLayer(const QString &direction) { QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); if (selectedIndex.isValid()) { - QVariant rowData = m_RenderWindowModel.value(m_CurrentRendererName)->data(selectedIndex, Qt::DisplayRole); - + QVariant rowData = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); mitk::DataNode* dataNode = GetDataStorage()->GetNamedNode(rowData.toString().toStdString()); - mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_CurrentRendererName.toStdString()); + const mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_Controls.comboBoxRenderWindowSelection->currentText().toStdString()); + if ("up" == direction) { m_RenderWindowLayerController->MoveNodeUp(dataNode, selectedRenderer); } else { m_RenderWindowLayerController->MoveNodeDown(dataNode, selectedRenderer); - } - - m_RenderWindowModel.value(m_CurrentRendererName)->UpdateTableForRenderWindow(m_RenderWindowLayerController->GetLayerStack(selectedRenderer, true)); + m_Controls.renderWindowTableView->clearSelection(); } } + +void QmitkRenderWindowManagerView::ResetRenderer() +{ + const mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_Controls.comboBoxRenderWindowSelection->currentText().toStdString()); + + m_RenderWindowLayerController->ResetRenderer(true, selectedRenderer); + m_Controls.renderWindowTableView->clearSelection(); +} + +void QmitkRenderWindowManagerView::ClearRenderer() +{ + const mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_Controls.comboBoxRenderWindowSelection->currentText().toStdString()); + + m_RenderWindowLayerController->ResetRenderer(false, selectedRenderer); + m_Controls.renderWindowTableView->clearSelection(); +} + +void QmitkRenderWindowManagerView::ChangeViewDirection(const QString &viewDirection) +{ + mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(m_Controls.comboBoxRenderWindowSelection->currentText().toStdString()); + + m_RenderWindowViewDirectionController->SetViewDirectionOfRenderer(viewDirection.toStdString(), selectedRenderer); +} + +void QmitkRenderWindowManagerView::NodeAdded(const mitk::DataNode* node) +{ + // initially set new node as invisible in all render windows + // this way, each single renderer overwrites the common renderer and the node is invisible + // until it is inserted in the node list of a render window + m_RenderWindowLayerController->HideDataNodeInAllRenderer(node); +} diff --git a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h index a78e78b69b..cd069680f4 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.h @@ -1,82 +1,92 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QMITKRENDERWINDOWMANAGERVIEW_H #define QMITKRENDERWINDOWMANAGERVIEW_H // render window manager plugin #include "ui_QmitkRenderWindowManagerControls.h" -#include "QmitkLayerManagerAddNodeWidget.h" +#include "QmitkLayerManagerAddLayerWidget.h" // render window manager module +#include +#include #include #include "QmitkVisibilityDelegate.h" -// core module -#include // blueberry #include // qt #include #include /** * @brief RenderWindowManager */ class QmitkRenderWindowManagerView : public QmitkAbstractView { Q_OBJECT public: + static const std::string VIEW_ID; -public Q_SLOTS: +protected: + + virtual void SetFocus() override; + + virtual void CreateQtPartControl(QWidget* parent) override; + + void SetUpConnections(); + +private Q_SLOTS: + /** * @brief called when the user changes the render window selection in the combo box */ void OnRenderWindowSelectionChanged(const QString &renderWindowId); - void ShowAddDataNodeWidget(); - void AddDataNode(mitk::DataNode* dataNode); - void RemoveDataNode(); - void SetAsBaseDataNode(); - - void MoveDataNode(const QString &direction); + void ShowAddLayerWidget(); + void AddLayer(mitk::DataNode* dataNode); + void RemoveLayer(); + void SetAsBaseLayer(); -protected: + void MoveLayer(const QString &direction); - virtual void SetFocus() override; + void ResetRenderer(); + void ClearRenderer(); - virtual void CreateQtPartControl(QWidget* parent) override; - - void SetUpConnections(); + void ChangeViewDirection(const QString &viewDirection); private: + /** + * @brief set each data node invisible in all render windows, as soon as the node is added to the data storage + */ + void NodeAdded(const mitk::DataNode* node) override; + // the Qt parent of our GUI QWidget* m_Parent; Ui::QmitkRenderWindowManagerControls m_Controls; - QMap m_RenderWindowModel; - QmitkVisibilityDelegate* m_VisibilityDelegate; - QString m_CurrentRendererName; - - mitk::RenderWindowLayerController* m_RenderWindowLayerController; - QmitkLayerManagerAddNodeWidget* m_AddDataNodeWidget; + std::unique_ptr m_RenderWindowDataModel; + std::unique_ptr m_RenderWindowLayerController; + std::unique_ptr m_RenderWindowViewDirectionController; + QmitkLayerManagerAddLayerWidget* m_AddLayerWidget; }; #endif // QMITKRENDERWINDOWMANAGERVIEW_H