diff --git a/Modules/QtWidgets/src/QmitkDataStorageListInspector.cpp b/Modules/QtWidgets/src/QmitkDataStorageListInspector.cpp index a5d3182d1f..37e57944f5 100644 --- a/Modules/QtWidgets/src/QmitkDataStorageListInspector.cpp +++ b/Modules/QtWidgets/src/QmitkDataStorageListInspector.cpp @@ -1,61 +1,61 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical Image Computing. 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 QmitkDataStorageListInspector::QmitkDataStorageListInspector(QWidget* parent/* = nullptr*/) : QmitkAbstractDataStorageInspector(parent) { m_Controls.setupUi(this); m_Controls.view->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.view->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.view->setAlternatingRowColors(true); m_StorageModel = new QmitkDataStorageDefaultListModel(this); m_Controls.view->setModel(m_StorageModel); } QAbstractItemView* QmitkDataStorageListInspector::GetView() { return m_Controls.view; -}; +} const QAbstractItemView* QmitkDataStorageListInspector::GetView() const { return m_Controls.view; -}; +} void QmitkDataStorageListInspector::Initialize() { m_StorageModel->SetDataStorage(m_DataStorage.Lock()); m_StorageModel->SetNodePredicate(m_NodePredicate); m_Connector->SetView(m_Controls.view); } void QmitkDataStorageListInspector::SetSelectionMode(SelectionMode mode) { m_Controls.view->setSelectionMode(mode); } QmitkDataStorageListInspector::SelectionMode QmitkDataStorageListInspector::GetSelectionMode() const { return m_Controls.view->selectionMode(); -}; +} diff --git a/Modules/RenderWindowManager/files.cmake b/Modules/RenderWindowManager/files.cmake index 5e95f08b7a..8d8bb99f84 100644 --- a/Modules/RenderWindowManager/files.cmake +++ b/Modules/RenderWindowManager/files.cmake @@ -1,19 +1,11 @@ set(H_FILES - include/QmitkRenderWindowDataModel.h - include/mitkRenderWindowLayerController.h - include/mitkRenderWindowViewDirectionController.h - include/mitkRenderWindowLayerUtilities.h + include/mitkRenderWindowViewDirectionController.h + include/mitkRenderWindowLayerUtilities.h ) set(CPP_FILES - QmitkRenderWindowDataModel.cpp - - mitkRenderWindowLayerController.cpp - mitkRenderWindowViewDirectionController.cpp - mitkRenderWindowLayerUtilities.cpp -) - -set(MOC_H_FILES - include/QmitkRenderWindowDataModel.h + mitkRenderWindowLayerController.cpp + mitkRenderWindowViewDirectionController.cpp + mitkRenderWindowLayerUtilities.cpp ) diff --git a/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h b/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h deleted file mode 100644 index b96a518bc2..0000000000 --- a/Modules/RenderWindowManager/include/QmitkRenderWindowDataModel.h +++ /dev/null @@ -1,69 +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 QMITKRENDERWINDOWDATAMODEL_H -#define QMITKRENDERWINDOWDATAMODEL_H - -// render window manager module -#include "MitkRenderWindowManagerExports.h" -#include "mitkRenderWindowLayerUtilities.h" - -//mitk core -#include -#include - -// qt -#include - -/* -* @brief This class extends the 'QAbstractTableModel' to meet the specific requirements of the QmitkRenderWindowDataModel. -*/ -class MITKRENDERWINDOWMANAGER_EXPORT QmitkRenderWindowDataModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - - QmitkRenderWindowDataModel(QObject* parent = nullptr); - ~QmitkRenderWindowDataModel() override; - - ////////////////////////////////////////////////////////////////////////// - /// overridden functions from QAbstractItemModel - ////////////////////////////////////////////////////////////////////////// - Qt::ItemFlags flags(const QModelIndex &index) const override; - QVariant data(const QModelIndex &index, int role) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - ////////////////////////////////////////////////////////////////////////// - /// end override - ///////////////////////////////////////////////////////////////////////// - - void SetDataStorage(mitk::DataStorage::Pointer dataStorage); - void SetCurrentRenderer(std::string rendererName); - mitk::BaseRenderer* GetCurrentRenderer() const { return m_BaseRenderer.GetPointer(); } - void DataChanged(const mitk::DataNode* dataNode); - -private: - - mitk::DataStorage::Pointer m_DataStorage; - mitk::BaseRenderer::Pointer m_BaseRenderer; - RenderWindowLayerUtilities::LayerStack m_TempLayerStack; - -}; - -#endif // QMITKRENDERWINDOWDATAMODEL_H diff --git a/Modules/RenderWindowManager/include/mitkRenderWindowLayerController.h b/Modules/RenderWindowManager/include/mitkRenderWindowLayerController.h index 9000f6f6d3..d81a6bf2e7 100644 --- a/Modules/RenderWindowManager/include/mitkRenderWindowLayerController.h +++ b/Modules/RenderWindowManager/include/mitkRenderWindowLayerController.h @@ -1,169 +1,177 @@ /*=================================================================== 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 module #include "MitkRenderWindowManagerExports.h" #include "mitkRenderWindowLayerUtilities.h" // mitk core #include #include #include namespace mitk { /** * The RenderWindowLayerController is used to manipulate the 'layer', 'fixedLayer' and 'visible' property of a given data node. * The 'layer' property is used to denote the layer level of a data node. Data from nodes on higher layer level are rendered * on top of data from nodes on lower layer level. It can be changed using the 'MoveNode*'-functions. * * To view the data of a data node only in a specific renderer, the "InsertLayerNode'-function should be used. It inserts the * given node into the specified renderer and sets the corresponding properties. * To hide the data in the common renderer view (all renderer), the 'HideDataNodeInAllRenderer'-function can be used. * Inserting and showing a data node in a specific renderer / render window, will overwrite the properties of the common renderer view. * * For more information about the data node properties for specific renderer, see mitk::DataNode- and mitk::PropertyList-classes. * * Functions with 'mitk::BaseRenderer* renderer' have 'nullptr' as their default argument. Using the nullptr * these functions operate on all base renderer. Giving a specific base renderer will modify the node only for the given renderer. */ class MITKRENDERWINDOWMANAGER_EXPORT RenderWindowLayerController { public: RenderWindowLayerController(); /** * @brief Set the data storage on which to work. */ void SetDataStorage(DataStorage::Pointer dataStorage); /** * @brief Set the controlled base renderer. */ void SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer); // 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. * * @param dataNode The data node whose layer is to be modified. * @param renderer Pointer to the renderer instance for which the data node property should be modified. * If it is a nullptr (default) all controlled renderer will be affected. */ void SetBaseDataNode(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Insert the given data node at the specified layer for the given renderer. * * @param dataNode The data node that should be inserted. * @param layer The layer value for the "layer" property of the data node (insertion level). "layer = RenderWindowLayerUtilities::TOP_LAYER_INDEX" (default) inserts the given data node at the top of the node stack (topmost layer). * @param renderer Pointer to the renderer instance for which the data node should be inserted. * If it is a nullptr (default) all controlled renderer will be affected. * * @post After a successful call, the "fixedLayer" and "visibility" property will be true and the "layer" property will be set correctly. */ void InsertLayerNode(DataNode* dataNode, int layer = RenderWindowLayerUtilities::TOP_LAYER_INDEX, const BaseRenderer* renderer = nullptr); /** * @brief Remove the given data node for the given renderer. * * @param dataNode The data node that should be removed. * @param renderer Pointer to the renderer instance for which the data node should be removed. * If it is a nullptr (default) all controlled renderer will be affected. * * @post After a successful call, the "fixedLayer" and "visibility" property will be false and the "layer" property will be deleted. */ void RemoveLayerNode(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** + * @brief Move the data node to the given layer. This will change only the "layer" property. + * + * @param dataNode The data node that should be moved. + * @param renderer Pointer to the renderer instance for which the data node should be moved. + * If it is a nullptr (default) all controlled renderer will be affected. + */ + bool MoveNodeToPosition(DataNode* dataNode, int newLayer, const BaseRenderer* renderer = nullptr); + /** * @brief Set the node in the given renderer as the topmost layer. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected. */ bool MoveNodeToFront(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Set the node in the given renderer as the lowermost layer. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected. */ bool MoveNodeToBack(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Move the node in the given renderer one layer down. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected. */ bool MoveNodeUp(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Move the node in the given renderer one layer up. This will change only the "layer" property. * * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be moved. * If it is a nullptr (default) all controlled renderer will be affected. */ bool MoveNodeDown(DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Set the visibility of the given data node for the given renderer. * * @param visibility Boolean to set the "visible" property of the given data node. * @param dataNode The data node that should be moved. * @param renderer Pointer to the renderer instance for which the data node should be modified. * If it is a nullptr (default) all controlled renderer will be affected. * * @post After a successful call , the "visibility" property will be set to the "visibility" value. */ void SetVisibilityOfDataNode(bool visiblity, DataNode* dataNode, const BaseRenderer* renderer = nullptr); /** * @brief Hide the given data node by setting the "visible" property of the data node for * all controlled renderer to false. * Later setting the "visible" property of the data node for a certain renderer will overwrite * the same property of the common renderer. * * @param dataNode The data node that should be hid. * * @post After a successful call , the "visibility" property will be set to the false. */ void HideDataNodeInAllRenderer(const DataNode* dataNode); /** * @brief Reset the given render window: * If "onlyVisibility = true": set all data nodes for the given 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. * * @param visibility Boolean to define the reset mode. * @param renderer Pointer to the renderer instance for which the data node should be reset. * If it is a nullptr (default) all controlled renderer will be affected. * * @post After a successful call , the "visibility" property will be set to the "false" value (except for the base node). * If "onlyVisibility = false": additionally the "fixedLayer" property will be false and the "layer" property will be deleted. */ void ResetRenderer(bool onlyVisibility = true, const BaseRenderer* renderer = nullptr); private: void InsertLayerNodeInternal(DataNode* dataNode, int layer, const BaseRenderer* renderer = nullptr); DataStorage::Pointer m_DataStorage; RenderWindowLayerUtilities::RendererVector m_ControlledRenderer; }; } // namespace mitk #endif // MITKRENDERWINDOWLAYERCONTROLLER_H diff --git a/Modules/RenderWindowManager/include/mitkRenderWindowLayerUtilities.h b/Modules/RenderWindowManager/include/mitkRenderWindowLayerUtilities.h index e119c43c10..df52c62cf2 100644 --- a/Modules/RenderWindowManager/include/mitkRenderWindowLayerUtilities.h +++ b/Modules/RenderWindowManager/include/mitkRenderWindowLayerUtilities.h @@ -1,61 +1,71 @@ /*=================================================================== 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 module #include "MitkRenderWindowManagerExports.h" // mitk core #include #include #include +#include /** * @brief Render window layer helper functions to retrieve the currently valid layer stack */ -namespace RenderWindowLayerUtilities +namespace mitk { - typedef std::vector RendererVector; - typedef std::map> LayerStack; - - /** - * 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. - */ - const int BASE_LAYER_INDEX = 0; - /** - * The top layer index, denoting that no valid (positive) layer index is given and therefore the index should be resolved into the topmost layer index. - */ - const int TOP_LAYER_INDEX = -1; - - /** - * @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 their "fixedLayer" property set to true and their "layer" property set. - * - * If "renderer" = nullptr: a layer stack won't be created and an empty "LayerStack" will be returned. - * If "withBaseNode" = true: include the base node in the layer stack, if existing. - * If "withBaseNode" = false: exclude the base node from the layer stack. - * - * @param dataStorage Pointer to a data storage instance whose data nodes should be checked and possibly be included. - * @param renderer Pointer to the renderer instance for which the layer stack should be generated. - * @param withBaseNode Boolean to decide whether the base node should be included in or excluded from the layer stack. - */ - MITKRENDERWINDOWMANAGER_EXPORT LayerStack GetLayerStack(const mitk::DataStorage* dataStorage, const mitk::BaseRenderer* renderer, bool withBaseNode); - -} // namespace RenderWindowLayerUtilities + namespace RenderWindowLayerUtilities + { + typedef std::vector RendererVector; + typedef std::map> LayerStack; + + /** + * 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. + */ + const int BASE_LAYER_INDEX = 0; + /** + * The top layer index, denoting that no valid (positive) layer index is given and therefore the index should be resolved into the topmost layer index. + */ + const int TOP_LAYER_INDEX = -1; + + /** + * @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 their "fixedLayer" property set to true and their "layer" property set. + * + * If "renderer" = nullptr: a layer stack won't be created and an empty "LayerStack" will be returned. + * If "withBaseNode" = true: include the base node in the layer stack, if existing. + * If "withBaseNode" = false: exclude the base node from the layer stack. + * + * @param dataStorage Pointer to a data storage instance whose data nodes should be checked and possibly be included. + * @param renderer Pointer to the renderer instance for which the layer stack should be generated. + * @param withBaseNode Boolean to decide whether the base node should be included in or excluded from the layer stack. + */ + MITKRENDERWINDOWMANAGER_EXPORT LayerStack GetLayerStack(const DataStorage* dataStorage, const BaseRenderer* renderer, bool withBaseNode); + /** + * @brief Helper function to get a node predicate that can be used to filter render window specific data nodes. + * + * The data nodes must not be 'helper objects'. The must have set a 'fixed layer' property for the given renderer. + */ + MITKRENDERWINDOWMANAGER_EXPORT NodePredicateAnd::Pointer GetRenderWindowPredicate(const BaseRenderer* renderer); + + } // namespace RenderWindowLayerUtilities +} // namespace mitk #endif // MITKRENDERWINDOWLAYERUTILITIES_H diff --git a/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp b/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp deleted file mode 100644 index a8888f8042..0000000000 --- a/Modules/RenderWindowManager/src/QmitkRenderWindowDataModel.cpp +++ /dev/null @@ -1,208 +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. - -===================================================================*/ - -// render window manager UI module -#include "QmitkRenderWindowDataModel.h" - -#include "QmitkCustomVariants.h" - -QmitkRenderWindowDataModel::QmitkRenderWindowDataModel(QObject* parent /*= nullptr*/) - : QAbstractTableModel(parent) -{ - // nothing here -} - -QmitkRenderWindowDataModel::~QmitkRenderWindowDataModel() -{ - if (m_DataStorage.IsNotNull()) - { - m_DataStorage->ChangedNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); - m_DataStorage->RemoveNodeEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowDataModel::DataChanged)); - } -} - -int QmitkRenderWindowDataModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const -{ - if (parent.isValid()) - { - return 0; - } - - return static_cast(m_TempLayerStack.size()); -} - -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(); - } - - 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 && 0 == index.column()) - { - bool visibility = false; - dataNode->GetVisibility(visibility, m_BaseRenderer); - if (visibility) - { - return Qt::Checked; - } - else - { - return Qt::Unchecked; - } - } - 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("Show/hide data node."); - } - else if (1 == index.column()) - { - return QVariant("Name of the data node."); - } - } - else if (Qt::UserRole == role) - { - // user role always returns a reference to the data node, - // which can be used to modify the data node in the data storage - return QVariant::fromValue(dataNode); - } - } - return QVariant(); -} - -Qt::ItemFlags QmitkRenderWindowDataModel::flags(const QModelIndex &index) const -{ - Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - 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 (0 == section) - { - return QVariant("Visibility"); - } - else if (1 == section) - { - return QVariant("Data node"); - } - } - return QVariant(); -} - -bool QmitkRenderWindowDataModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/) -{ - if (!index.isValid()) - { - return false; - } - - 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()); - - if (Qt::PartiallyChecked == newCheckState || Qt::Checked == newCheckState) - { - dataNode->SetVisibility(true, m_BaseRenderer); - } - else - { - dataNode->SetVisibility(false, m_BaseRenderer); - } - emit dataChanged(index, index); - 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::SetCurrentRenderer(std::string renderWindowName) -{ - m_BaseRenderer = mitk::BaseRenderer::GetByName(renderWindowName); - if (m_DataStorage.IsNotNull()) - { - DataChanged(nullptr); - } -} - -void QmitkRenderWindowDataModel::DataChanged(const mitk::DataNode* /*dataNode*/) -{ - if (m_BaseRenderer.IsNotNull()) - { - // 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/mitkRenderWindowLayerController.cpp b/Modules/RenderWindowManager/src/mitkRenderWindowLayerController.cpp index 7f47606503..4760a2ca4e 100644 --- a/Modules/RenderWindowManager/src/mitkRenderWindowLayerController.cpp +++ b/Modules/RenderWindowManager/src/mitkRenderWindowLayerController.cpp @@ -1,500 +1,568 @@ /*=================================================================== 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 module #include "mitkRenderWindowLayerController.h" mitk::RenderWindowLayerController::RenderWindowLayerController() : m_DataStorage(nullptr) { // nothing here } void mitk::RenderWindowLayerController::SetDataStorage(DataStorage::Pointer dataStorage) { if (m_DataStorage != dataStorage) { // set the new data storage m_DataStorage = dataStorage; } } void mitk::RenderWindowLayerController::SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer) { if (m_ControlledRenderer != controlledRenderer) { // set the new set of controlled renderer m_ControlledRenderer = controlledRenderer; } } 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 RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, true); if (!stackedLayers.empty()) { // see if base layer exists RenderWindowLayerUtilities::LayerStack::iterator layerStackIterator = stackedLayers.find(RenderWindowLayerUtilities::BASE_LAYER_INDEX); 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); } } // "RenderWindowLayerUtilities::BASE_LAYER_INDEX" indicates the base data node --> set as new background dataNode->SetIntProperty("layer", RenderWindowLayerUtilities::BASE_LAYER_INDEX, 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 /*= RenderWindowLayerUtilities::TOP_LAYER_INDEX*/, 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 (RenderWindowLayerUtilities::BASE_LAYER_INDEX == layer) { // "RenderWindowLayerUtilities::BASE_LAYER_INDEX" indicates the base data node --> set as new background (overwrite current base node if needed) SetBaseDataNode(dataNode, renderer); } else { InsertLayerNodeInternal(dataNode, layer, renderer); } } } 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 RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (stackedLayers.empty()) { // no layer stack for the current renderer if (RenderWindowLayerUtilities::TOP_LAYER_INDEX == 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 (RenderWindowLayerUtilities::TOP_LAYER_INDEX == newLayer) { // get the first value (highest int-key -> topmost layer) - // +1 indicates inserting the node above the topmost layer + // + 1 indicates inserting the node above the topmost layer newLayer = stackedLayers.begin()->first + 1; } else { - // see if layer is already taken - 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); - } + MoveNodeToPosition(dataNode, newLayer, renderer); + return; } } // update data storage (the "data node model") dataNode->SetIntProperty("layer", newLayer, renderer); dataNode->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } 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()) { RemoveLayerNode(dataNode, renderer); } } } else { // "remove" node from the renderer list dataNode->GetPropertyList(renderer)->DeleteProperty("layer"); dataNode->SetBoolProperty("fixedLayer", false, renderer); dataNode->SetVisibility(false, renderer); dataNode->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } +bool mitk::RenderWindowLayerController::MoveNodeToPosition(DataNode* dataNode, int newLayer, const BaseRenderer* renderer /*= nullptr*/) +{ + if (nullptr == dataNode) + { + return false; + } + + if (nullptr == renderer) + { + // move data node to position in all controlled renderer + for (const auto& renderer : m_ControlledRenderer) + { + if (renderer.IsNotNull()) + { + MoveNodeToPosition(dataNode, newLayer, renderer); + // we don't store/need the returned boolean value + return false; + } + } + } + else + { + // get the layer stack without the base node of the current renderer + RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); + if (!stackedLayers.empty()) + { + // get the current layer value of the given data node + int currentLayer; + bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer); + if (wasFound && currentLayer != newLayer) + { + // move the given data node to the specified layer + dataNode->SetIntProperty("layer", newLayer, renderer); + + int upperBound; + int lowerBound; + int step; + if (currentLayer < newLayer) + { + // move node up + upperBound = newLayer + 1; + lowerBound = currentLayer + 1; + step = -1; // move all other nodes one step down + } + else + { + upperBound = currentLayer; + lowerBound = newLayer; + step = 1; // move all other nodes one step up + } + + // move all other data nodes between the upper and the lower bound + for (auto& layer : stackedLayers) + { + if (layer.second != dataNode && layer.first < upperBound && layer.first >= lowerBound) + { + layer.second->SetIntProperty("layer", layer.first + step, renderer); + } + // else: current data node is the selected data node or + // was previously already above the selected data node or + // was previously already below the new layer position + } + dataNode->Modified(); + mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); + return true; + } + // else: data node has no layer information or is already at the specified position + } + // else: do not work with empty layer stack + } + return false; +} + bool mitk::RenderWindowLayerController::MoveNodeToFront(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { if (nullptr == dataNode) { return false; } if (nullptr == renderer) { // move data node to front in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { MoveNodeToFront(dataNode, renderer); // we don't store/need the returned boolean value return false; } } } else { // get the layer stack without the base node of the current renderer RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (!stackedLayers.empty()) { // 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 above the current topmost layer dataNode->SetIntProperty("layer", topmostLayer+1, renderer); dataNode->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); return true; } // 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 BaseRenderer* renderer /*= nullptr*/) { if (nullptr == dataNode) { return false; } if (nullptr == renderer) { // move data node to back in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { MoveNodeToBack(dataNode, renderer); // we don't store/need the returned boolean value return false; } } } else { // get the layer stack without the base node of the current renderer RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (!stackedLayers.empty()) { // get the last value (lowest int-key) // cannot be the base layer as the base node was excluded by the 'GetLayerStack'-function 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.first < currentLayer) { layer.second->SetIntProperty("layer", layer.first + 1, renderer); } // else: current data node is the selected data node or // was previously already above the selected data node } dataNode->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); return true; } // 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(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { if (nullptr == dataNode) { return false; } if (nullptr == renderer) { // move data node down in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { MoveNodeUp(dataNode, renderer); // we don't store/need the returned boolean value return false; } } } else { // get the layer stack without the base node of the current renderer RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (!stackedLayers.empty()) { // get the current layer value of the given data node int currentLayer; bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer); if (wasFound) { // 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); dataNode->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); return true; } // 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 } // else: do not work with empty layer stack } return false; } bool mitk::RenderWindowLayerController::MoveNodeDown(DataNode* dataNode, const BaseRenderer* renderer /*= nullptr*/) { if (nullptr == dataNode) { return false; } if (nullptr == renderer) { // move data node up in all controlled renderer for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { MoveNodeDown(dataNode, renderer); // we don't store/need the returned boolean value return false; } } } else { // get the layer stack without the base node of the current renderer RenderWindowLayerUtilities::LayerStack stackedLayers = RenderWindowLayerUtilities::GetLayerStack(m_DataStorage, renderer, false); if (!stackedLayers.empty()) { // get the current layer value of the given data node int currentLayer; bool wasFound = dataNode->GetIntProperty("layer", currentLayer, renderer); if (wasFound) { // 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); dataNode->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); return true; } // 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 } // else: do not work with empty layer stack } return false; } 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); } } } else { dataNode->SetVisibility(visibility, renderer); dataNode->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } void mitk::RenderWindowLayerController::HideDataNodeInAllRenderer(const DataNode* dataNode) { if (nullptr == dataNode) { return; } for (const auto& renderer : m_ControlledRenderer) { if (renderer.IsNotNull()) { dataNode->GetPropertyList(renderer)->SetBoolProperty("visible", false); } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } 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 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 (RenderWindowLayerUtilities::BASE_LAYER_INDEX == layerLevel) { // set base data node visibility to true layer.second->SetVisibility(true, renderer); } else { // set visibility of all other data nodes to false layer.second->SetVisibility(false, renderer); // modify layer node if (!onlyVisibility) { // clear mode: additionally remove layer node from current renderer layer.second->GetPropertyList(renderer)->DeleteProperty("layer"); layer.second->SetBoolProperty("fixedLayer", false, renderer); } } layer.second->Modified(); } mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); } } } diff --git a/Modules/RenderWindowManager/src/mitkRenderWindowLayerUtilities.cpp b/Modules/RenderWindowManager/src/mitkRenderWindowLayerUtilities.cpp index 29ac67fbd1..b3fd2e8a12 100644 --- a/Modules/RenderWindowManager/src/mitkRenderWindowLayerUtilities.cpp +++ b/Modules/RenderWindowManager/src/mitkRenderWindowLayerUtilities.cpp @@ -1,63 +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. ===================================================================*/ // render window manager module #include "mitkRenderWindowLayerUtilities.h" // mitk core -#include #include -#include +#include -RenderWindowLayerUtilities::LayerStack RenderWindowLayerUtilities::GetLayerStack(const mitk::DataStorage* dataStorage, const mitk::BaseRenderer* renderer, bool withBaseNode) +mitk::RenderWindowLayerUtilities::LayerStack mitk::RenderWindowLayerUtilities::GetLayerStack(const DataStorage* dataStorage, const 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) + NodePredicateAnd::Pointer combinedNodePredicate = GetRenderWindowPredicate(renderer); + DataStorage::SetOfObjects::ConstPointer filteredDataNodes = dataStorage->GetSubset(combinedNodePredicate); + for (DataStorage::SetOfObjects::ConstIterator it = filteredDataNodes->Begin(); it != filteredDataNodes->End(); ++it) { - mitk::DataNode::Pointer dataNode = it->Value(); + DataNode::Pointer dataNode = it->Value(); if (dataNode.IsNull()) { continue; } bool layerFound = dataNode->GetIntProperty("layer", layer, renderer); if (layerFound) { if (BASE_LAYER_INDEX != layer|| 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; } + +mitk::NodePredicateAnd::Pointer mitk::RenderWindowLayerUtilities::GetRenderWindowPredicate(const BaseRenderer* renderer) +{ + NodePredicateAnd::Pointer renderWindowPredicate = NodePredicateAnd::New(); + + NodePredicateProperty::Pointer helperObject = NodePredicateProperty::New("helper object", BoolProperty::New(true)); + NodePredicateProperty::Pointer fixedLayer = NodePredicateProperty::New("fixedLayer", BoolProperty::New(true), renderer); + + renderWindowPredicate->AddPredicate(NodePredicateNot::New(helperObject)); + renderWindowPredicate->AddPredicate(fixedLayer); + + return renderWindowPredicate; +} diff --git a/Modules/RenderWindowManagerUI/files.cmake b/Modules/RenderWindowManagerUI/files.cmake index a998c3cf7f..287bd2aef8 100644 --- a/Modules/RenderWindowManagerUI/files.cmake +++ b/Modules/RenderWindowManagerUI/files.cmake @@ -1,15 +1,19 @@ set(H_FILES - include/QmitkRenderWindowManipulatorWidget.h + include/QmitkDataStorageRenderWindowInspector.h + include/QmitkDataStorageRenderWindowListModel.h ) set(CPP_FILES - QmitkRenderWindowManipulatorWidget.cpp + QmitkDataStorageRenderWindowInspector.cpp + QmitkDataStorageRenderWindowListModel.cpp + ) set(MOC_H_FILES - include/QmitkRenderWindowManipulatorWidget.h + include/QmitkDataStorageRenderWindowInspector.h. + include/QmitkDataStorageRenderWindowListModel.h ) set(UI_FILES - src/QmitkRenderWindowManipulatorWidget.ui + src/QmitkDataStorageRenderWindowInspector.ui ) \ No newline at end of file diff --git a/Modules/RenderWindowManagerUI/include/QmitkDataStorageRenderWindowInspector.h b/Modules/RenderWindowManagerUI/include/QmitkDataStorageRenderWindowInspector.h new file mode 100644 index 0000000000..a646220ef1 --- /dev/null +++ b/Modules/RenderWindowManagerUI/include/QmitkDataStorageRenderWindowInspector.h @@ -0,0 +1,95 @@ +/*=================================================================== + +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 QMITKDATASTORAGERENDERWINDOWINSPECTOR_H +#define QMITKDATASTORAGERENDERWINDOWINSPECTOR_H + +// render window manager UI module +#include "MitkRenderWindowManagerUIExports.h" +#include "ui_QmitkDataStorageRenderWindowInspector.h" + +// render window manager module +#include +#include + +// qt widgets module +#include + +/** +* The 'QmitkDataStorageRenderWindowInspector' offers a GUI to manipulate the base renderer / render windows of the MITK workbench. +* The widgets supports adding a layer to an active render window, moving layers up and down, removing layers, +* resetting layers (hiding them) or removing all layers at once. +* +* In order to use this widget, a (e.g.) plugin has to set the controlled renderer, which will be forwarded to +* a render window view direction controller. +*/ +class MITKRENDERWINDOWMANAGERUI_EXPORT QmitkDataStorageRenderWindowInspector : public QmitkAbstractDataStorageInspector +{ + Q_OBJECT + +public: + + QmitkDataStorageRenderWindowInspector(QWidget* parent = nullptr); + + // override from 'QmitkAbstractDataStorageInspector' + /** + * @brief See 'QmitkAbstractDataStorageInspector' + */ + virtual QAbstractItemView* GetView() override; + /** + * @brief See 'QmitkAbstractDataStorageInspector' + */ + virtual const QAbstractItemView* GetView() const override; + /** + * @brief See 'QmitkAbstractDataStorageInspector' + */ + virtual void SetSelectionMode(SelectionMode mode) override; + /** + * @brief See 'QmitkAbstractDataStorageInspector' + */ + virtual SelectionMode GetSelectionMode() const override; + /** + * @brief Set the controlled base renderer. + */ + void SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer); + /** + * @brief Set the currently selected render window. + * + * @param renderWindowId the text inside the combo box + */ + void SetActiveRenderWindow(const QString& renderWindowId); + +private Q_SLOTS: + + void SetAsBaseLayer(); + + void ResetRenderer(); + void ClearRenderer(); + + void ChangeViewDirection(const QString& viewDirection); + +private: + + virtual void Initialize() override; + void SetUpConnections(); + + Ui::QmitkDataStorageRenderWindowInspector m_Controls; + + std::unique_ptr m_StorageModel; + std::unique_ptr m_RenderWindowViewDirectionController; +}; + +#endif // QMITKDATASTORAGERENDERWINDOWINSPECTOR_H diff --git a/Modules/RenderWindowManagerUI/include/QmitkDataStorageRenderWindowListModel.h b/Modules/RenderWindowManagerUI/include/QmitkDataStorageRenderWindowListModel.h new file mode 100644 index 0000000000..76340f4474 --- /dev/null +++ b/Modules/RenderWindowManagerUI/include/QmitkDataStorageRenderWindowListModel.h @@ -0,0 +1,109 @@ +/*=================================================================== + +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 QMITKDATASTORAGERENDERWINDOWLISTMODEL_H +#define QMITKDATASTORAGERENDERWINDOWLISTMODEL_H + +// render window manager UI model +#include "MitkRenderWindowManagerUIExports.h" + +// render window manager module +#include "mitkRenderWindowLayerController.h" +#include "mitkRenderWindowLayerUtilities.h" + +//mitk core +#include + +// qt widgets module +#include + +/* +* @brief The 'QmitkDataStorageRenderWindowListModel' is a list model derived from the 'QmitkAbstractDataStorageModel'. +*/ +class MITKRENDERWINDOWMANAGERUI_EXPORT QmitkDataStorageRenderWindowListModel : public QmitkAbstractDataStorageModel +{ + Q_OBJECT + +public: + + QmitkDataStorageRenderWindowListModel(QObject* parent = nullptr); + ~QmitkDataStorageRenderWindowListModel() override; + + // override from 'QmitkAbstractDataStorageModel' + /** + * @brief See 'QmitkAbstractDataStorageModel' + */ + void DataStorageChanged() override; + /** + * @brief See 'QmitkAbstractDataStorageModel' + */ + void NodePredicateChanged() override; + /** + * @brief See 'QmitkAbstractDataStorageModel' + */ + void NodeAdded(const mitk::DataNode* node) override; + /** + * @brief See 'QmitkAbstractDataStorageModel' + */ + void NodeChanged(const mitk::DataNode* node) override; + /** + * @brief See 'QmitkAbstractDataStorageModel' + */ + void NodeRemoved(const mitk::DataNode* node) override; + + // override from 'QAbstractItemModel' + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex& child) const override; + + int rowCount(const QModelIndex& parent = QModelIndex()) const override; + int columnCount(const QModelIndex& parent = QModelIndex()) const override; + + QVariant data(const QModelIndex& index, int role) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; + + Qt::ItemFlags flags(const QModelIndex& index) const override; + + Qt::DropActions supportedDropActions() const override; + Qt::DropActions supportedDragActions() const override; + QStringList mimeTypes() const override; + QMimeData* mimeData(const QModelIndexList& indexes) const override; + + bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; + + void SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer); + + void SetCurrentRenderer(mitk::BaseRenderer* baseRenderer); + mitk::BaseRenderer* GetCurrentRenderer() const { return m_BaseRenderer.GetPointer(); } + + /** + * @brief Use the RenderWindowLayerController to insert the given data node into all controlled render windows. + * The new node is placed on top of all existing layer nodes in the render window. + * + * @param dataNode The data node that should be inserted. + */ + void AddDataNodeToAllRenderer(mitk::DataNode* dataNode); + +private: + + void UpdateModelData(); + + std::unique_ptr m_RenderWindowLayerController; + mitk::BaseRenderer::Pointer m_BaseRenderer; + mitk::RenderWindowLayerUtilities::LayerStack m_LayerStack; + +}; + +#endif // QMITKDATASTORAGERENDERWINDOWLISTMODEL_H diff --git a/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h b/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h deleted file mode 100644 index e08edafbce..0000000000 --- a/Modules/RenderWindowManagerUI/include/QmitkRenderWindowManipulatorWidget.h +++ /dev/null @@ -1,108 +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 QMITKRENDERWINDOWMANIPULATORWIDGET_H -#define QMITKRENDERWINDOWMANIPULATORWIDGET_H - -// render window manager UI module -#include "MitkRenderWindowManagerUIExports.h" -#include "ui_QmitkRenderWindowManipulatorWidget.h" - -// render window manager module -#include -#include -#include - -// qt -#include - -/** -* The QmitkRenderWindowManipulatorWidget offers a GUI to manipulate the base renderer / render windows of the MITK workbench. -* The widgets supports adding a layer to an active render window, moving layers up and down, removing layers, -* resetting layers (hiding them) or removing all layers at once. -* -* In order to use this widget, a (e.g.) plugin has to set the controlled renderer, which will be forwarded to -* a render window layer controller and a render window view direction controller. -* The plugin also has to provide a Q_SLOT that is connected to the 'AddLayerButtonClicked'-Q_SIGNAL of this widget. -* This allows for a customized add-layer functionality. -*/ -class MITKRENDERWINDOWMANAGERUI_EXPORT QmitkRenderWindowManipulatorWidget : public QWidget -{ - Q_OBJECT - -public: - - QmitkRenderWindowManipulatorWidget(mitk::DataStorage::Pointer dataStorage, QWidget* parent = nullptr); - /** - * @brief Set the controlled base renderer. - */ - void SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer); - /** - * @brief Set the currently selected render window - * - * @param renderWindowId the text inside the combo box - */ - void SetActiveRenderWindow(const QString &renderWindowId); - /** - * @brief Use the RenderWindowLayerController to insert the given data node into the currently active render window. - * The new node is placed on top of all existing layer nodes in that render window. - * - * @param dataNode The data node that should be inserted. - */ - void AddLayer(mitk::DataNode* dataNode); - /** - * @brief Use the RenderWindowLayerController to insert the given data node into all controlled render windows. - * The new node is placed on top of all existing layer nodes in the render window. - * - * @param dataNode The data node that should be inserted. - */ - void AddLayerToAllRenderer(mitk::DataNode* dataNode); - /** - * @brief Use the RenderWindowLayerController to hide the given data node in the currently active render window. - * - * @param dataNode The data node that should be hid. - */ - void HideDataNodeInAllRenderer(const mitk::DataNode* dataNode); - -Q_SIGNALS: - void AddLayerButtonClicked(); - -private Q_SLOTS: - - void RemoveLayer(); - void SetAsBaseLayer(); - - void MoveLayer(const QString &direction); - - void ResetRenderer(); - void ClearRenderer(); - - void ChangeViewDirection(const QString &viewDirection); - -private: - - void Init(); - void SetUpConnections(); - - Ui::QmitkRenderWindowManipulatorWidget m_Controls; - - mitk::DataStorage::Pointer m_DataStorage; - std::unique_ptr m_RenderWindowDataModel; - std::unique_ptr m_RenderWindowLayerController; - std::unique_ptr m_RenderWindowViewDirectionController; -}; - -#endif // QMITKRENDERWINDOWMANIPULATORWIDGET_H diff --git a/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.cpp b/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.cpp new file mode 100644 index 0000000000..7ea07d286e --- /dev/null +++ b/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.cpp @@ -0,0 +1,163 @@ +/*=================================================================== + +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 UI module +#include "QmitkDataStorageRenderWindowInspector.h" + +#include "QmitkCustomVariants.h" + +// mitk core +#include + +// qt +#include + +QmitkDataStorageRenderWindowInspector::QmitkDataStorageRenderWindowInspector(QWidget* parent /*=nullptr*/) + : QmitkAbstractDataStorageInspector(parent) +{ + m_Controls.setupUi(this); + + // initialize the render window view direction controller + // and set the controlled renderer (in constructor) and the data storage + m_RenderWindowViewDirectionController = std::make_unique(); + + // create a new model + m_StorageModel = std::make_unique(this); + + m_Controls.renderWindowListView->setModel(m_StorageModel.get()); + m_Controls.renderWindowListView->setEditTriggers(QAbstractItemView::NoEditTriggers); + m_Controls.renderWindowListView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_Controls.renderWindowListView->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_Controls.renderWindowListView->setAlternatingRowColors(true); + m_Controls.renderWindowListView->setDragEnabled(true); + m_Controls.renderWindowListView->setDropIndicatorShown(true); + m_Controls.renderWindowListView->setAcceptDrops(true); + + SetUpConnections(); +} + +QAbstractItemView* QmitkDataStorageRenderWindowInspector::GetView() +{ + return m_Controls.renderWindowListView; +}; + +const QAbstractItemView* QmitkDataStorageRenderWindowInspector::GetView() const +{ + return m_Controls.renderWindowListView; +}; + +void QmitkDataStorageRenderWindowInspector::SetSelectionMode(SelectionMode mode) +{ + m_Controls.renderWindowListView->setSelectionMode(mode); +} + +QmitkDataStorageRenderWindowInspector::SelectionMode QmitkDataStorageRenderWindowInspector::GetSelectionMode() const +{ + return m_Controls.renderWindowListView->selectionMode(); +} + +void QmitkDataStorageRenderWindowInspector::Initialize() +{ + m_StorageModel->SetDataStorage(m_DataStorage.Lock()); + m_StorageModel->SetNodePredicate(m_NodePredicate); + + m_RenderWindowViewDirectionController->SetDataStorage(m_DataStorage.Lock()); + + m_Connector->SetView(m_Controls.renderWindowListView); +} + +void QmitkDataStorageRenderWindowInspector::SetUpConnections() +{ + connect(m_Controls.pushButtonSetAsBaseLayer, SIGNAL(clicked()), this, SLOT(SetAsBaseLayer())); + + connect(m_Controls.pushButtonResetRenderer, SIGNAL(clicked()), this, SLOT(ResetRenderer())); + connect(m_Controls.pushButtonClearRenderer, SIGNAL(clicked()), this, SLOT(ClearRenderer())); + + 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())); +} + +void QmitkDataStorageRenderWindowInspector::SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer) +{ + m_StorageModel->SetControlledRenderer(controlledRenderer); + m_RenderWindowViewDirectionController->SetControlledRenderer(controlledRenderer); +} + +void QmitkDataStorageRenderWindowInspector::SetActiveRenderWindow(const QString& renderWindowId) +{ + mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(renderWindowId.toStdString()); + if (nullptr == selectedRenderer) + { + return; + } + + m_StorageModel->SetCurrentRenderer(selectedRenderer); + mitk::SliceNavigationController::ViewDirection viewDirection = selectedRenderer->GetSliceNavigationController()->GetDefaultViewDirection(); + switch (viewDirection) + { + 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; + } +} + +void QmitkDataStorageRenderWindowInspector::SetAsBaseLayer() +{ + /* + QModelIndex selectedIndex = m_Controls.renderWindowListView->currentIndex(); + if (selectedIndex.isValid()) + { + QVariant qvariantDataNode = m_StorageModel->data(selectedIndex, Qt::UserRole); + if (qvariantDataNode.canConvert()) + { + mitk::DataNode* dataNode = qvariantDataNode.value(); + m_RenderWindowLayerController->SetBaseDataNode(dataNode, m_StorageModel->GetCurrentRenderer()); + m_Controls.renderWindowListView->clearSelection(); + } + } + */ +} + +void QmitkDataStorageRenderWindowInspector::ResetRenderer() +{ + //m_RenderWindowLayerController->ResetRenderer(true, m_StorageModel->GetCurrentRenderer()); + m_Controls.renderWindowListView->clearSelection(); +} + +void QmitkDataStorageRenderWindowInspector::ClearRenderer() +{ + //m_RenderWindowLayerController->ResetRenderer(false, m_StorageModel->GetCurrentRenderer()); + m_Controls.renderWindowListView->clearSelection(); +} + +void QmitkDataStorageRenderWindowInspector::ChangeViewDirection(const QString& viewDirection) +{ + m_RenderWindowViewDirectionController->SetViewDirectionOfRenderer(viewDirection.toStdString(), m_StorageModel->GetCurrentRenderer()); +} diff --git a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui b/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.ui similarity index 67% rename from Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui rename to Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.ui index 01e6a1b05f..07c5b4c9ad 100644 --- a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.ui +++ b/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowInspector.ui @@ -1,120 +1,92 @@ - QmitkRenderWindowManipulatorWidget - + QmitkDataStorageRenderWindowInspector + 0 0 308 246 0 0 0 0 Render window manager Render window overview - + - - + + - Add Layer + Reset render window - - + + - Remove layer + Clear render window - + Set as base layer - - - - Move up - - - - - - - Move down - - - - - - - Reset render window - - - - - - - Clear render window - - - - + Axial true - + Coronal - + Sagittal diff --git a/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowListModel.cpp b/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowListModel.cpp new file mode 100644 index 0000000000..058322f48c --- /dev/null +++ b/Modules/RenderWindowManagerUI/src/QmitkDataStorageRenderWindowListModel.cpp @@ -0,0 +1,311 @@ +/*=================================================================== + +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 UI module +#include "QmitkDataStorageRenderWindowListModel.h" + +// qt widgets module +#include "QmitkCustomVariants.h" +#include "QmitkEnums.h" +#include "QmitkMimeTypes.h" +#include "QmitkNodeDescriptorManager.h" + +QmitkDataStorageRenderWindowListModel::QmitkDataStorageRenderWindowListModel(QObject* parent /*= nullptr*/) + : QmitkAbstractDataStorageModel(parent) +{ + m_RenderWindowLayerController = std::make_unique(); +} + +QmitkDataStorageRenderWindowListModel::~QmitkDataStorageRenderWindowListModel() +{ + // nothing here +} + +void QmitkDataStorageRenderWindowListModel::DataStorageChanged() +{ + m_RenderWindowLayerController->SetDataStorage(m_DataStorage.Lock()); + UpdateModelData(); +} + +void QmitkDataStorageRenderWindowListModel::NodePredicateChanged() +{ + UpdateModelData(); +} + +void QmitkDataStorageRenderWindowListModel::NodeAdded(const mitk::DataNode* node) +{ + // add a node to each render window specific list (or to a global list initially) + AddDataNodeToAllRenderer(const_cast(node)); + UpdateModelData(); +} + +void QmitkDataStorageRenderWindowListModel::NodeChanged(const mitk::DataNode* /*node*/) +{ + // nothing here, since the "'NodeChanged'-event is currently sent far too often + //UpdateModelData(); +} + +void QmitkDataStorageRenderWindowListModel::NodeRemoved(const mitk::DataNode* /*node*/) +{ + // update model data to create a new list without the removed data node + UpdateModelData(); +} + +QModelIndex QmitkDataStorageRenderWindowListModel::index(int row, int column, const QModelIndex& parent) const +{ + bool hasIndex = this->hasIndex(row, column, parent); + if (hasIndex) + { + return this->createIndex(row, column); + } + + return QModelIndex(); +} + +QModelIndex QmitkDataStorageRenderWindowListModel::parent(const QModelIndex& /*child*/) const +{ + return QModelIndex(); +} + +int QmitkDataStorageRenderWindowListModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const +{ + if (parent.isValid()) + { + return 0; + } + + return static_cast(m_LayerStack.size()); +} + +int QmitkDataStorageRenderWindowListModel::columnCount(const QModelIndex& parent /*= QModelIndex()*/) const +{ + if (parent.isValid()) + { + return 0; + } + + return 1; +} + +QVariant QmitkDataStorageRenderWindowListModel::data(const QModelIndex& index, int role) const +{ + if (!index.isValid() || this != index.model()) + { + return QVariant(); + } + + if (index.row() < 0 || index.row() >= static_cast(m_LayerStack.size())) + { + return QVariant(); + } + + mitk::RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_LayerStack.begin(); + std::advance(layerStackIt, index.row()); + mitk::DataNode* dataNode = layerStackIt->second; + + if (Qt::CheckStateRole == role) + { + bool visibility = false; + dataNode->GetVisibility(visibility, m_BaseRenderer); + if (visibility) + { + return Qt::Checked; + } + else + { + return Qt::Unchecked; + } + } + else if (Qt::DisplayRole == role) + { + return QVariant(QString::fromStdString(dataNode->GetName())); + } + else if (Qt::ToolTipRole == role) + { + return QVariant("Name of the data node."); + } + else if (Qt::DecorationRole == role) + { + QmitkNodeDescriptor* nodeDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode); + return nodeDescriptor->GetIcon(dataNode); + } + else if (Qt::UserRole == role || QmitkDataNodeRawPointerRole == role) + { + // user role always returns a reference to the data node, + // which can be used to modify the data node in the data storage + return QVariant::fromValue(dataNode); + } + else if (QmitkDataNodeRole == role) + { + return QVariant::fromValue(mitk::DataNode::Pointer(dataNode)); + } + + return QVariant(); +} + +bool QmitkDataStorageRenderWindowListModel::setData(const QModelIndex& index, const QVariant& value, int role /*= Qt::EditRole*/) +{ + if (!index.isValid() || this != index.model()) + { + return false; + } + + if (index.row() < 0 || index.row() >= static_cast(m_LayerStack.size())) + { + return false; + } + + mitk::RenderWindowLayerUtilities::LayerStack::const_iterator layerStackIt = m_LayerStack.begin(); + std::advance(layerStackIt, index.row()); + mitk::DataNode* dataNode = layerStackIt->second; + if (Qt::CheckStateRole == role) + { + Qt::CheckState newCheckState = static_cast(value.toInt()); + bool isVisible = newCheckState; + dataNode->SetVisibility(isVisible, m_BaseRenderer); + + emit dataChanged(index, index); + mitk::RenderingManager::GetInstance()->RequestUpdate(m_BaseRenderer->GetRenderWindow()); + return true; + } + return false; +} + +Qt::ItemFlags QmitkDataStorageRenderWindowListModel::flags(const QModelIndex &index) const +{ + if (this != index.model()) + { + return Qt::NoItemFlags; + } + + if (!index.isValid()) + { + return Qt::ItemIsDropEnabled; + } + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; +} + +Qt::DropActions QmitkDataStorageRenderWindowListModel::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +Qt::DropActions QmitkDataStorageRenderWindowListModel::supportedDragActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +QStringList QmitkDataStorageRenderWindowListModel::mimeTypes() const +{ + QStringList types = QAbstractItemModel::mimeTypes(); + types << QmitkMimeTypes::DataNodePtrs; + return types; +} + +QMimeData* QmitkDataStorageRenderWindowListModel::mimeData(const QModelIndexList& indexes) const +{ + QMimeData* mimeData = new QMimeData(); + QByteArray encodedData; + + QDataStream stream(&encodedData, QIODevice::WriteOnly); + + for (const auto& index : indexes) + { + if (index.isValid()) + { + auto dataNode = data(index, QmitkDataNodeRawPointerRole).value(); + stream << reinterpret_cast(dataNode); + } + } + + mimeData->setData(QmitkMimeTypes::DataNodePtrs, encodedData); + return mimeData; +} + +bool QmitkDataStorageRenderWindowListModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) +{ + if (action == Qt::IgnoreAction) + { + return true; + } + + if (!data->hasFormat(QmitkMimeTypes::DataNodePtrs)) + { + return false; + } + + if (column > 0) + { + return false; + } + + if (parent.isValid()) + { + int layer = -1; + auto dataNode = this->data(parent, QmitkDataNodeRawPointerRole).value(); + if (nullptr != dataNode) + { + dataNode->GetIntProperty("layer", layer, m_BaseRenderer); + } + + auto dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data); + for (const auto& dataNode : dataNodeList) + { + m_RenderWindowLayerController->MoveNodeToPosition(dataNode, layer, m_BaseRenderer); + } + + UpdateModelData(); + return true; + } + + return false; +} + +void QmitkDataStorageRenderWindowListModel::SetControlledRenderer(mitk::RenderWindowLayerUtilities::RendererVector controlledRenderer) +{ + m_RenderWindowLayerController->SetControlledRenderer(controlledRenderer); +} + +void QmitkDataStorageRenderWindowListModel::SetCurrentRenderer(mitk::BaseRenderer* baseRenderer) +{ + if (m_BaseRenderer != baseRenderer) + { + m_BaseRenderer = baseRenderer; + UpdateModelData(); + } +} + +void QmitkDataStorageRenderWindowListModel::AddDataNodeToAllRenderer(mitk::DataNode* dataNode) +{ + m_RenderWindowLayerController->InsertLayerNode(dataNode); +} + +void QmitkDataStorageRenderWindowListModel::UpdateModelData() +{ + if (!m_DataStorage.IsExpired()) + { + auto dataStorage = m_DataStorage.Lock(); + if (m_BaseRenderer.IsNotNull()) + { + // update the model, so that it will be filled with the nodes of the new data storage + beginResetModel(); + // get the current layer stack of the given base renderer + m_LayerStack = mitk::RenderWindowLayerUtilities::GetLayerStack(dataStorage, m_BaseRenderer, true); + endResetModel(); + } + } +} diff --git a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp b/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp deleted file mode 100644 index c8ecd4bee7..0000000000 --- a/Modules/RenderWindowManagerUI/src/QmitkRenderWindowManipulatorWidget.cpp +++ /dev/null @@ -1,216 +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. - -===================================================================*/ - -// render window manager UI module -#include "QmitkRenderWindowManipulatorWidget.h" - -#include "QmitkCustomVariants.h" - -// mitk core -#include - -// qt -#include - -QmitkRenderWindowManipulatorWidget::QmitkRenderWindowManipulatorWidget(mitk::DataStorage::Pointer dataStorage, QWidget* parent /*=nullptr*/) - : QWidget(parent) - , m_DataStorage(dataStorage) -{ - Init(); -} - -void QmitkRenderWindowManipulatorWidget::Init() -{ - // create GUI from the Qt Designer's .ui file - m_Controls.setupUi(this); - - // 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(m_DataStorage); - m_RenderWindowViewDirectionController->SetDataStorage(m_DataStorage); - - // create a new model - m_RenderWindowDataModel = std::make_unique(this); - m_RenderWindowDataModel->SetDataStorage(m_DataStorage); - - m_Controls.renderWindowTableView->setModel(m_RenderWindowDataModel.get()); - m_Controls.renderWindowTableView->setEditTriggers(QAbstractItemView::NoEditTriggers); - m_Controls.renderWindowTableView->horizontalHeader()->setStretchLastSection(true); - m_Controls.renderWindowTableView->setSelectionBehavior(QAbstractItemView::SelectRows); - m_Controls.renderWindowTableView->setSelectionMode(QAbstractItemView::SingleSelection); - - SetUpConnections(); -} - -void QmitkRenderWindowManipulatorWidget::SetUpConnections() -{ - // signal to signal connection - connect(m_Controls.pushButtonAddLayer, SIGNAL(clicked()), this, SIGNAL(AddLayerButtonClicked())); - 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(m_Controls.pushButtonResetRenderer, SIGNAL(clicked()), this, SLOT(ResetRenderer())); - connect(m_Controls.pushButtonClearRenderer, SIGNAL(clicked()), this, SLOT(ClearRenderer())); - - 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())); -} - -void QmitkRenderWindowManipulatorWidget::SetControlledRenderer(RenderWindowLayerUtilities::RendererVector controlledRenderer) -{ - m_RenderWindowLayerController->SetControlledRenderer(controlledRenderer); - m_RenderWindowViewDirectionController->SetControlledRenderer(controlledRenderer); -} - -void QmitkRenderWindowManipulatorWidget::SetActiveRenderWindow(const QString &renderWindowId) -{ - std::string currentRendererName = renderWindowId.toStdString(); - m_RenderWindowDataModel->SetCurrentRenderer(currentRendererName); - - mitk::BaseRenderer* selectedRenderer = mitk::BaseRenderer::GetByName(currentRendererName); - if (nullptr == selectedRenderer) - { - return; - } - - mitk::SliceNavigationController::ViewDirection viewDirection = selectedRenderer->GetSliceNavigationController()->GetDefaultViewDirection(); - switch (viewDirection) - { - 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; - } -} - -void QmitkRenderWindowManipulatorWidget::AddLayer(mitk::DataNode* dataNode) -{ - m_RenderWindowLayerController->InsertLayerNode(dataNode, -1, m_RenderWindowDataModel->GetCurrentRenderer()); -} - -void QmitkRenderWindowManipulatorWidget::AddLayerToAllRenderer(mitk::DataNode* dataNode) -{ - m_RenderWindowLayerController->InsertLayerNode(dataNode, -1, nullptr); -} - -void QmitkRenderWindowManipulatorWidget::HideDataNodeInAllRenderer(const mitk::DataNode* dataNode) -{ - m_RenderWindowLayerController->HideDataNodeInAllRenderer(dataNode); -} - -void QmitkRenderWindowManipulatorWidget::RemoveLayer() -{ - QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); - if (selectedIndex.isValid()) - { - - QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); - if (qvariantDataNode.canConvert()) - { - mitk::DataNode* dataNode = qvariantDataNode.value(); - m_RenderWindowLayerController->RemoveLayerNode(dataNode, m_RenderWindowDataModel->GetCurrentRenderer()); - m_Controls.renderWindowTableView->clearSelection(); - } - } -} - -void QmitkRenderWindowManipulatorWidget::SetAsBaseLayer() -{ - QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); - if (selectedIndex.isValid()) - { - QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); - if (qvariantDataNode.canConvert()) - { - mitk::DataNode* dataNode = qvariantDataNode.value(); - m_RenderWindowLayerController->SetBaseDataNode(dataNode, m_RenderWindowDataModel->GetCurrentRenderer()); - m_Controls.renderWindowTableView->clearSelection(); - } - } -} - -void QmitkRenderWindowManipulatorWidget::MoveLayer(const QString &direction) -{ - QModelIndex selectedIndex = m_Controls.renderWindowTableView->currentIndex(); - if (selectedIndex.isValid()) - { - QVariant qvariantDataNode = m_RenderWindowDataModel->data(selectedIndex, Qt::UserRole); - if (qvariantDataNode.canConvert()) - { - mitk::DataNode* dataNode = qvariantDataNode.value(); - const mitk::BaseRenderer* selectedRenderer = m_RenderWindowDataModel->GetCurrentRenderer(); - - bool success = false; - if ("up" == direction) - { - success = m_RenderWindowLayerController->MoveNodeUp(dataNode, selectedRenderer); - if (success) - { - // node has been successfully moved up - m_Controls.renderWindowTableView->selectRow(selectedIndex.row() - 1); - } - } - else - { - success = m_RenderWindowLayerController->MoveNodeDown(dataNode, selectedRenderer); - if (success) - { - // node has been successfully moved down - m_Controls.renderWindowTableView->selectRow(selectedIndex.row() + 1); - } - } - } - } -} - -void QmitkRenderWindowManipulatorWidget::ResetRenderer() -{ - m_RenderWindowLayerController->ResetRenderer(true, m_RenderWindowDataModel->GetCurrentRenderer()); - m_Controls.renderWindowTableView->clearSelection(); -} - -void QmitkRenderWindowManipulatorWidget::ClearRenderer() -{ - m_RenderWindowLayerController->ResetRenderer(false, m_RenderWindowDataModel->GetCurrentRenderer()); - m_Controls.renderWindowTableView->clearSelection(); -} - -void QmitkRenderWindowManipulatorWidget::ChangeViewDirection(const QString &viewDirection) -{ - m_RenderWindowViewDirectionController->SetViewDirectionOfRenderer(viewDirection.toStdString(), m_RenderWindowDataModel->GetCurrentRenderer()); -} 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 1307b4045e..78e159649f 100644 --- a/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp +++ b/Plugins/org.mitk.gui.qt.renderwindowmanager/src/internal/QmitkRenderWindowManagerView.cpp @@ -1,114 +1,72 @@ /*=================================================================== 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 core #include #include const std::string QmitkRenderWindowManagerView::VIEW_ID = "org.mitk.views.renderwindowmanager"; void QmitkRenderWindowManagerView::SetFocus() { // nothing here } void QmitkRenderWindowManagerView::CreateQtPartControl(QWidget* parent) { // create GUI widgets m_Controls.setupUi(parent); // add custom render window manager UI widget to the 'renderWindowManagerTab' - m_RenderWindowManipulatorWidget = new QmitkRenderWindowManipulatorWidget(GetDataStorage(), parent); - m_RenderWindowManipulatorWidget->setObjectName(QStringLiteral("m_RenderWindowManipulatorWidget")); - m_Controls.verticalLayout->addWidget(m_RenderWindowManipulatorWidget); + m_RenderWindowInspector = new QmitkDataStorageRenderWindowInspector(parent); + m_RenderWindowInspector->SetDataStorage(GetDataStorage()); + m_RenderWindowInspector->setObjectName(QStringLiteral("m_RenderWindowManipulatorWidget")); + m_Controls.verticalLayout->addWidget(m_RenderWindowInspector); SetControlledRenderer(); for (const auto& renderer : m_ControlledRenderer) { m_Controls.comboBoxRenderWindowSelection->addItem(renderer->GetName()); } OnRenderWindowSelectionChanged(m_Controls.comboBoxRenderWindowSelection->itemText(0)); connect(m_Controls.comboBoxRenderWindowSelection, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnRenderWindowSelectionChanged(const QString&))); - connect(m_RenderWindowManipulatorWidget, SIGNAL(AddLayerButtonClicked()), this, SLOT(OnAddLayerButtonClicked())); } void QmitkRenderWindowManagerView::SetControlledRenderer() { const mitk::RenderingManager::RenderWindowVector allRegisteredRenderWindows = mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows(); mitk::BaseRenderer* baseRenderer = nullptr; for (const auto &renderWindow : allRegisteredRenderWindows) { baseRenderer = mitk::BaseRenderer::GetInstance(renderWindow); if (nullptr != baseRenderer) { m_ControlledRenderer.push_back(baseRenderer); } } - m_RenderWindowManipulatorWidget->SetControlledRenderer(m_ControlledRenderer); + m_RenderWindowInspector->SetControlledRenderer(m_ControlledRenderer); } void QmitkRenderWindowManagerView::OnRenderWindowSelectionChanged(const QString &renderWindowId) { - m_RenderWindowManipulatorWidget->SetActiveRenderWindow(renderWindowId); -} - -void QmitkRenderWindowManagerView::OnAddLayerButtonClicked() -{ - QList nodes = GetDataManagerSelection(); - for (mitk::DataNode* dataNode : nodes) - { - if (nullptr != dataNode) - { - m_RenderWindowManipulatorWidget->AddLayer(dataNode); - - // get child nodes of the current node - mitk::DataStorage::SetOfObjects::ConstPointer derivedNodes = GetDataStorage()->GetDerivations(dataNode, nullptr, false); - for (mitk::DataStorage::SetOfObjects::ConstIterator it = derivedNodes->Begin(); it != derivedNodes->End(); ++it) - { - m_RenderWindowManipulatorWidget->AddLayer(it->Value()); - } - } - } -} - -void QmitkRenderWindowManagerView::NodeAdded(const mitk::DataNode* node) -{ - bool global = false; - node->GetBoolProperty("globalObject_RWM", global); - if (global) - { - // initially insert new point set node into the node list of all render windows - // the node object of a new point set won't be visible due to its "helper object" property set to true - m_RenderWindowManipulatorWidget->AddLayerToAllRenderer(const_cast(node)); - } - else - { - // 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 into the node list of a render windows - m_RenderWindowManipulatorWidget->HideDataNodeInAllRenderer(node); - } + m_RenderWindowInspector->SetActiveRenderWindow(renderWindowId); } 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 ba9743fb77..1c1cbdcff1 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,66 @@ /*=================================================================== 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" // render window manager UI module -#include +#include -// blueberry -#include - -// qt +// mitk gui qt common plugin #include /** * @brief RenderWindowManager */ class QmitkRenderWindowManagerView : public QmitkAbstractView { Q_OBJECT public: static const std::string VIEW_ID; protected: virtual void SetFocus() override; virtual void CreateQtPartControl(QWidget* parent) override; private Q_SLOTS: /** * @brief Called when the user changes the render window selection in the combo box. * * @param renderWindowId The text inside the combo box. */ void OnRenderWindowSelectionChanged(const QString &renderWindowId); - /** - * @brief Called when the 'AddLayer'-button of he render window manipulator widget has been pushed. - */ - void OnAddLayerButtonClicked(); private: void SetControlledRenderer(); - /** - * @brief Reacts to a node that has been added to the data storage. - * 1. Insert new node into the node list of all render windows, if it is an "globalObject_RWM"-node. - * or else - * 2. Set 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; - QmitkRenderWindowManipulatorWidget* m_RenderWindowManipulatorWidget; - RenderWindowLayerUtilities::RendererVector m_ControlledRenderer; + QmitkDataStorageRenderWindowInspector* m_RenderWindowInspector; + mitk::RenderWindowLayerUtilities::RendererVector m_ControlledRenderer; }; #endif // QMITKRENDERWINDOWMANAGERVIEW_H