diff --git a/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp b/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp index 5cb7f5eb82..4b410b4dd3 100644 --- a/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp +++ b/Modules/Core/src/Interactions/mitkInteractionSchemeSwitcher.cpp @@ -1,96 +1,101 @@ /*=================================================================== 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 "mitkInteractionSchemeSwitcher.h" // us #include "usGetModuleContext.h" #include "usModuleContext.h" // mitk core #include "mitkInteractionEventObserver.h" mitk::InteractionSchemeSwitcher::InteractionSchemeSwitcher() : m_InteractionScheme(MITKStandard) { // nothing here } mitk::InteractionSchemeSwitcher::~InteractionSchemeSwitcher() { // nothing here } void mitk::InteractionSchemeSwitcher::SetInteractionScheme(mitk::InteractionEventHandler* interactionEventHandler, InteractionScheme interactionScheme) { + if (nullptr == interactionEventHandler) + { + return; + } + switch (interactionScheme) { // MITK MODE case MITKStandard: { interactionEventHandler->SetEventConfig("DisplayConfigMITK.xml"); break; } case MITKRotationUncoupled: { interactionEventHandler->SetEventConfig("DisplayConfigMITKRotationUnCoupled.xml"); break; } case MITKRotationCoupled: { interactionEventHandler->SetEventConfig("DisplayConfigMITKRotation.xml"); break; } case MITKSwivel: { interactionEventHandler->SetEventConfig("DisplayConfigMITKSwivel.xml"); break; } // PACS MODE case PACSStandard: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); break; } case PACSLevelWindow: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSLevelWindow.xml"); break; } case PACSPan: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSPan.xml"); break; } case PACSScroll: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSScroll.xml"); break; } case PACSZoom: { interactionEventHandler->SetEventConfig("DisplayConfigPACS.xml"); interactionEventHandler->AddEventConfig("DisplayConfigPACSZoom.xml"); break; } } m_InteractionScheme = interactionScheme; InvokeEvent(InteractionSchemeChangedEvent()); } diff --git a/Modules/QtWidgets/include/QmitkMxNMultiWidget.h b/Modules/QtWidgets/include/QmitkMxNMultiWidget.h index 061aeea8f2..06ec04b91e 100644 --- a/Modules/QtWidgets/include/QmitkMxNMultiWidget.h +++ b/Modules/QtWidgets/include/QmitkMxNMultiWidget.h @@ -1,152 +1,154 @@ /*=================================================================== 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. ===================================================================*/ #ifndef QMITKMXNMULTIWIDGET_H #define QMITKMXNMULTIWIDGET_H // qt widgets module #include "MitkQtWidgetsExports.h" #include "QmitkRenderWindowWidget.h" // mitk core #include #include #include #include +#include // qt #include class QHBoxLayout; class QVBoxLayout; class QGridLayout; class QSpacerItem; class QmitkRenderWindow; namespace mitk { class RenderingManager; } /** * @brief The 'QmitkMxNMultiWidget' is a QWidget that is used to display multiple render windows at once. * Render windows can dynamically be added and removed to change the layout of the multi widget. This * is done by using the 'ResetLayout'-function to define a layout. This will automatically add or remove * the appropriate number of render window widgets. * Several functions exist to retrieve specific render window(s) (widgets) by their position or name. * * The class uses the 'DisplayActionEventBroadcast' and 'DisplayActionEventHandler' classes to * load a state machine and set an event configuration. PACS mode is used per default. * Using the 'Synchronize' function the user can enable or disable the synchronization of display action events. * See 'DisplayActionEventFunctions'-class for the different synchronized and non-synchronized functions used. */ class MITKQTWIDGETS_EXPORT QmitkMxNMultiWidget : public QWidget { Q_OBJECT public: using RenderWindowWidgetPointer = std::shared_ptr; using RenderWindowWidgetMap = std::map>; using RenderWindowHash = QHash; QmitkMxNMultiWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, mitk::RenderingManager* renderingManager = nullptr, mitk::BaseRenderer::RenderingMode::Type renderingMode = mitk::BaseRenderer::RenderingMode::Standard, const QString& multiWidgetName = "mxnmulti"); virtual ~QmitkMxNMultiWidget() = default; void SetDataStorage(mitk::DataStorage* dataStorage); void InitializeRenderWindowWidgets(); mitk::InteractionEventHandler::Pointer GetInteractionEventHandler() { return m_DisplayActionEventBroadcast.GetPointer(); }; void ResetLayout(int row, int column); void Synchronize(bool synchronized); + void SetInteractionScheme(mitk::InteractionSchemeSwitcher::InteractionScheme scheme); RenderWindowWidgetMap GetRenderWindowWidgets() const; RenderWindowWidgetPointer GetRenderWindowWidget(int row, int column) const; RenderWindowWidgetPointer GetRenderWindowWidget(const QString& widgetName) const; RenderWindowHash GetRenderWindows() const; QmitkRenderWindow* GetRenderWindow(int row, int column) const; QmitkRenderWindow* GetRenderWindow(const QString& widgetName) const; void SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget); RenderWindowWidgetPointer GetActiveRenderWindowWidget() const; RenderWindowWidgetPointer GetFirstRenderWindowWidget() const; RenderWindowWidgetPointer GetLastRenderWindowWidget() const; unsigned int GetNumberOfRenderWindowWidgets() const; void RequestUpdate(const QString& widgetName); void RequestUpdateAll(); void ForceImmediateUpdate(const QString& widgetName); void ForceImmediateUpdateAll(); void ActivateAllCrosshairs(bool activate); const mitk::Point3D GetSelectedPosition(const QString& widgetName) const; public Q_SLOTS: void SetSelectedPosition(const QString& widgetName, const mitk::Point3D& newPosition); // mouse events void wheelEvent(QWheelEvent* e) override; void mousePressEvent(QMouseEvent* e) override; void moveEvent(QMoveEvent* e) override; Q_SIGNALS: void WheelMoved(QWheelEvent *); void Moved(); private: void InitializeGUI(); void InitializeDisplayActionEventHandling(); void CreateRenderWindowWidget(); void DestroyRenderWindowWidget(); void FillMultiWidgetLayout(); QString GetNameFromIndex(int row, int column) const; QString GetNameFromIndex(size_t index) const; QGridLayout* m_MxNMultiWidgetLayout; RenderWindowWidgetMap m_RenderWindowWidgets; RenderWindowWidgetPointer m_ActiveRenderWindowWidget; int m_MultiWidgetRows; int m_MultiWidgetColumns; int m_PlaneMode; mitk::RenderingManager* m_RenderingManager; mitk::BaseRenderer::RenderingMode::Type m_RenderingMode; QString m_MultiWidgetName; mitk::DisplayActionEventBroadcast::Pointer m_DisplayActionEventBroadcast; std::unique_ptr m_DisplayActionEventHandler; mitk::DataStorage::Pointer m_DataStorage; }; #endif // QMITKMXNMULTIWIDGET_H diff --git a/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp b/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp index d206f56208..6ab1cacbbc 100644 --- a/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp +++ b/Modules/QtWidgets/src/QmitkMxNMultiWidget.cpp @@ -1,431 +1,438 @@ /*=================================================================== 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 "QmitkMxNMultiWidget.h" #include #include #include #include // mitk core #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // qt #include QmitkMxNMultiWidget::QmitkMxNMultiWidget(QWidget* parent, Qt::WindowFlags f/* = 0*/, mitk::RenderingManager* renderingManager/* = nullptr*/, mitk::BaseRenderer::RenderingMode::Type renderingMode/* = mitk::BaseRenderer::RenderingMode::Standard*/, const QString& multiWidgetName/* = "mxnmulti"*/) : QWidget(parent, f) , m_MxNMultiWidgetLayout(nullptr) , m_MultiWidgetRows(0) , m_MultiWidgetColumns(0) , m_PlaneMode(0) , m_RenderingManager(renderingManager) , m_RenderingMode(renderingMode) , m_MultiWidgetName(multiWidgetName) , m_DisplayActionEventBroadcast(nullptr) , m_DisplayActionEventHandler(nullptr) , m_DataStorage(nullptr) { InitializeGUI(); InitializeDisplayActionEventHandling(); resize(QSize(364, 477).expandedTo(minimumSizeHint())); } void QmitkMxNMultiWidget::SetDataStorage(mitk::DataStorage* dataStorage) { if (dataStorage == m_DataStorage) { return; } m_DataStorage = dataStorage; // set new data storage for the render window widgets for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->SetDataStorage(m_DataStorage); } } void QmitkMxNMultiWidget::InitializeRenderWindowWidgets() { m_MultiWidgetRows = 1; m_MultiWidgetColumns = 1; CreateRenderWindowWidget(); InitializeGUI(); } void QmitkMxNMultiWidget::ResetLayout(int row, int column) { m_MultiWidgetRows = row; m_MultiWidgetColumns = column; int requiredRenderWindowWidgets = m_MultiWidgetRows * m_MultiWidgetColumns; int existingRenderWindowWidgets = m_RenderWindowWidgets.size(); int difference = requiredRenderWindowWidgets - existingRenderWindowWidgets; while(0 < difference) { // more render window widgets needed CreateRenderWindowWidget(); --difference; } while(0 > difference) { // less render window widgets needed DestroyRenderWindowWidget(); ++difference; } InitializeGUI(); } void QmitkMxNMultiWidget::Synchronize(bool synchronized) { auto allObserverTags = m_DisplayActionEventHandler->GetAllObserverTags(); for (auto observerTag : allObserverTags) { m_DisplayActionEventHandler->DisconnectObserver(observerTag); } if (synchronized) { mitk::StdFunctionCommand::ActionFunction actionFunction = mitk::DisplayActionEventFunctions::MoveCameraSynchronizedAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayMoveEvent(nullptr, mitk::Vector2D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::SetCrosshairSynchronizedAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplaySetCrosshairEvent(nullptr, mitk::Point3D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::ZoomCameraSynchronizedAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayZoomEvent(nullptr, 0.0, mitk::Point2D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::ScrollSliceStepperSynchronizedAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayScrollEvent(nullptr, 0), actionFunction); } else { mitk::StdFunctionCommand::ActionFunction actionFunction = mitk::DisplayActionEventFunctions::MoveSenderCameraAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayMoveEvent(nullptr, mitk::Vector2D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::SetCrosshairAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplaySetCrosshairEvent(nullptr, mitk::Point3D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::ZoomSenderCameraAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayZoomEvent(nullptr, 0.0, mitk::Point2D()), actionFunction); actionFunction = mitk::DisplayActionEventFunctions::ScrollSliceStepperAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplayScrollEvent(nullptr, 0), actionFunction); } // use the standard 'set level window' action for both modes mitk::StdFunctionCommand::ActionFunction actionFunction = mitk::DisplayActionEventFunctions::SetLevelWindowAction(); m_DisplayActionEventHandler->ConnectDisplayActionEvent(mitk::DisplaySetLevelWindowEvent(nullptr, mitk::ScalarType(), mitk::ScalarType()), actionFunction); } +void QmitkMxNMultiWidget::SetInteractionScheme(mitk::InteractionSchemeSwitcher::InteractionScheme scheme) +{ + auto interactionSchemeSwitcher = mitk::InteractionSchemeSwitcher::New(); + auto interactionEventHandler = GetInteractionEventHandler(); + interactionSchemeSwitcher->SetInteractionScheme(interactionEventHandler, scheme); +} + QmitkMxNMultiWidget::RenderWindowWidgetMap QmitkMxNMultiWidget::GetRenderWindowWidgets() const { return m_RenderWindowWidgets; } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetRenderWindowWidget(int row, int column) const { return GetRenderWindowWidget(GetNameFromIndex(row, column)); } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetRenderWindowWidget(const QString& widgetName) const { RenderWindowWidgetMap::const_iterator it = m_RenderWindowWidgets.find(widgetName); if (it != m_RenderWindowWidgets.end()) { return it->second; } return nullptr; } QmitkMxNMultiWidget::RenderWindowHash QmitkMxNMultiWidget::GetRenderWindows() const { RenderWindowHash result; // create QHash on demand auto renderWindowWidgets = GetRenderWindowWidgets(); for (const auto& renderWindowWidget : renderWindowWidgets) { result.insert(renderWindowWidget.first, renderWindowWidget.second->GetRenderWindow()); } return result; } QmitkRenderWindow* QmitkMxNMultiWidget::GetRenderWindow(int row, int column) const { return GetRenderWindow(GetNameFromIndex(row, column)); } QmitkRenderWindow* QmitkMxNMultiWidget::GetRenderWindow(const QString& widgetName) const { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { return renderWindowWidget->GetRenderWindow(); } return nullptr; } void QmitkMxNMultiWidget::SetActiveRenderWindowWidget(RenderWindowWidgetPointer activeRenderWindowWidget) { m_ActiveRenderWindowWidget = activeRenderWindowWidget; } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetActiveRenderWindowWidget() const { return m_ActiveRenderWindowWidget; } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetFirstRenderWindowWidget() const { if (!m_RenderWindowWidgets.empty()) { return m_RenderWindowWidgets.begin()->second; } else { return nullptr; } } QmitkMxNMultiWidget::RenderWindowWidgetPointer QmitkMxNMultiWidget::GetLastRenderWindowWidget() const { if (!m_RenderWindowWidgets.empty()) { return m_RenderWindowWidgets.rbegin()->second; } else { return nullptr; } } unsigned int QmitkMxNMultiWidget::GetNumberOfRenderWindowWidgets() const { return m_RenderWindowWidgets.size(); } void QmitkMxNMultiWidget::RequestUpdate(const QString& widgetName) { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { return renderWindowWidget->RequestUpdate(); } } void QmitkMxNMultiWidget::RequestUpdateAll() { for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->RequestUpdate(); } } void QmitkMxNMultiWidget::ForceImmediateUpdate(const QString& widgetName) { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(widgetName); if (nullptr != renderWindowWidget) { renderWindowWidget->ForceImmediateUpdate(); } } void QmitkMxNMultiWidget::ForceImmediateUpdateAll() { for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->ForceImmediateUpdate(); } } void QmitkMxNMultiWidget::ActivateAllCrosshairs(bool activate) { for (const auto& renderWindowWidget : m_RenderWindowWidgets) { renderWindowWidget.second->ActivateCrosshair(activate); } } const mitk::Point3D QmitkMxNMultiWidget::GetSelectedPosition(const QString& /*widgetName*/) const { // see T26208 return mitk::Point3D(); } ////////////////////////////////////////////////////////////////////////// // PUBLIC SLOTS ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::SetSelectedPosition(const QString& widgetName, const mitk::Point3D& newPosition) { RenderWindowWidgetPointer renderWindowWidget; if (widgetName.isNull()) { renderWindowWidget = GetActiveRenderWindowWidget(); } else { renderWindowWidget = GetRenderWindowWidget(widgetName); } if (nullptr != renderWindowWidget) { renderWindowWidget->GetSliceNavigationController()->SelectSliceByPoint(newPosition); renderWindowWidget->RequestUpdate(); return; } MITK_ERROR << "Position can not be set for an unknown render window widget."; } ////////////////////////////////////////////////////////////////////////// // MOUSE EVENTS ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::wheelEvent(QWheelEvent* e) { emit WheelMoved(e); } void QmitkMxNMultiWidget::mousePressEvent(QMouseEvent* /*e*/) { } void QmitkMxNMultiWidget::moveEvent(QMoveEvent* e) { QWidget::moveEvent(e); // it is necessary to readjust the position of the overlays as the MultiWidget has moved // unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here emit Moved(); } ////////////////////////////////////////////////////////////////////////// // PRIVATE ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidget::InitializeGUI() { delete m_MxNMultiWidgetLayout; m_MxNMultiWidgetLayout = new QGridLayout(this); m_MxNMultiWidgetLayout->setContentsMargins(0, 0, 0, 0); setLayout(m_MxNMultiWidgetLayout); FillMultiWidgetLayout(); } void QmitkMxNMultiWidget::InitializeDisplayActionEventHandling() { m_DisplayActionEventBroadcast = mitk::DisplayActionEventBroadcast::New(); m_DisplayActionEventBroadcast->LoadStateMachine("DisplayInteraction.xml"); - m_DisplayActionEventBroadcast->SetEventConfig("DisplayConfigPACS.xml"); + m_DisplayActionEventBroadcast->SetEventConfig("DisplayConfigMITK.xml"); m_DisplayActionEventHandler = std::make_unique(); m_DisplayActionEventHandler->SetObservableBroadcast(m_DisplayActionEventBroadcast); Synchronize(true); } void QmitkMxNMultiWidget::CreateRenderWindowWidget() { // create the render window widget and connect signals / slots QString renderWindowWidgetName = GetNameFromIndex(m_RenderWindowWidgets.size()); RenderWindowWidgetPointer renderWindowWidget = std::make_shared(this, renderWindowWidgetName, m_DataStorage); renderWindowWidget->SetCornerAnnotationText(renderWindowWidgetName.toStdString()); // store the newly created render window widget with the UID m_RenderWindowWidgets.insert(std::make_pair(renderWindowWidgetName, renderWindowWidget)); } void QmitkMxNMultiWidget::DestroyRenderWindowWidget() { auto iterator = m_RenderWindowWidgets.find(GetNameFromIndex(m_RenderWindowWidgets.size() - 1)); if (iterator == m_RenderWindowWidgets.end()) { return; } // disconnect each signal of this render window widget RenderWindowWidgetPointer renderWindowWidgetToRemove = iterator->second; disconnect(renderWindowWidgetToRemove.get(), 0, 0, 0); // erase the render window from the map m_RenderWindowWidgets.erase(iterator); } void QmitkMxNMultiWidget::FillMultiWidgetLayout() { for (int row = 0; row < m_MultiWidgetRows; ++row) { for (int column = 0; column < m_MultiWidgetColumns; ++column) { RenderWindowWidgetPointer renderWindowWidget = GetRenderWindowWidget(row, column); if (nullptr != renderWindowWidget) { m_MxNMultiWidgetLayout->addWidget(renderWindowWidget.get(), row, column); SetActiveRenderWindowWidget(renderWindowWidget); } } } } QString QmitkMxNMultiWidget::GetNameFromIndex(int row, int column) const { if (0 <= row && m_MultiWidgetRows > row && 0 <= column && m_MultiWidgetColumns > column) { return GetNameFromIndex(row * m_MultiWidgetColumns + column); } return QString(); } QString QmitkMxNMultiWidget::GetNameFromIndex(size_t index) const { if (index <= m_RenderWindowWidgets.size()) { return m_MultiWidgetName + ".widget" + QString::number(index); } return QString(); } diff --git a/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.cpp b/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.cpp index bf802f1d33..02449c3630 100644 --- a/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.cpp +++ b/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.cpp @@ -1,248 +1,264 @@ /*=================================================================== 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 "QmitkMxNMultiWidgetEditor.h" #include #include #include #include #include // mxn multi widget editor plugin #include "QmitkMultiWidgetDecorationManager.h" // mitk qt widgets module #include #include #include const QString QmitkMxNMultiWidgetEditor::EDITOR_ID = "org.mitk.editors.mxnmultiwidget"; class QmitkMxNMultiWidgetEditor::Impl final { public: Impl(); ~Impl() = default; QmitkMxNMultiWidget* m_MxNMultiWidget; QmitkInteractionSchemeToolBar* m_InteractionSchemeToolBar; QmitkMultiWidgetConfigurationToolBar* m_ConfigurationToolBar; std::unique_ptr m_MultiWidgetDecorationManager; }; QmitkMxNMultiWidgetEditor::Impl::Impl() : m_MxNMultiWidget(nullptr) , m_InteractionSchemeToolBar(nullptr) , m_ConfigurationToolBar(nullptr) { // nothing here } ////////////////////////////////////////////////////////////////////////// // QmitkMxNMultiWidgetEditor ////////////////////////////////////////////////////////////////////////// QmitkMxNMultiWidgetEditor::QmitkMxNMultiWidgetEditor() : m_Impl(new Impl()) {} QmitkMxNMultiWidgetEditor::~QmitkMxNMultiWidgetEditor() { GetSite()->GetPage()->RemovePartListener(this); } QmitkRenderWindow* QmitkMxNMultiWidgetEditor::GetActiveQmitkRenderWindow() const { if (nullptr != m_Impl->m_MxNMultiWidget) { auto activeRenderWindowWidget = m_Impl->m_MxNMultiWidget->GetActiveRenderWindowWidget(); if (nullptr != activeRenderWindowWidget) { return activeRenderWindowWidget->GetRenderWindow(); } } return nullptr; } QHash QmitkMxNMultiWidgetEditor::GetQmitkRenderWindows() const { QHash result; if (nullptr == m_Impl->m_MxNMultiWidget) { return result; } result = m_Impl->m_MxNMultiWidget->GetRenderWindows(); return result; } QmitkRenderWindow* QmitkMxNMultiWidgetEditor::GetQmitkRenderWindow(const QString& id) const { if (nullptr == m_Impl->m_MxNMultiWidget) { return nullptr; } return m_Impl->m_MxNMultiWidget->GetRenderWindow(id); } mitk::Point3D QmitkMxNMultiWidgetEditor::GetSelectedPosition(const QString& id) const { if (nullptr == m_Impl->m_MxNMultiWidget) { return mitk::Point3D(); } return m_Impl->m_MxNMultiWidget->GetSelectedPosition(id); } void QmitkMxNMultiWidgetEditor::SetSelectedPosition(const mitk::Point3D& pos, const QString& id) { if (nullptr != m_Impl->m_MxNMultiWidget) { m_Impl->m_MxNMultiWidget->SetSelectedPosition(id, pos); } } void QmitkMxNMultiWidgetEditor::EnableDecorations(bool enable, const QStringList& decorations) { m_Impl->m_MultiWidgetDecorationManager->ShowDecorations(enable, decorations); } bool QmitkMxNMultiWidgetEditor::IsDecorationEnabled(const QString& decoration) const { return m_Impl->m_MultiWidgetDecorationManager->IsDecorationVisible(decoration); } QStringList QmitkMxNMultiWidgetEditor::GetDecorations() const { return m_Impl->m_MultiWidgetDecorationManager->GetDecorations(); } berry::IPartListener::Events::Types QmitkMxNMultiWidgetEditor::GetPartEventTypes() const { return Events::CLOSED | Events::OPENED; } void QmitkMxNMultiWidgetEditor::PartOpened(const berry::IWorkbenchPartReference::Pointer& partRef) { if (partRef->GetId() == QmitkMxNMultiWidgetEditor::EDITOR_ID) { m_Impl->m_MxNMultiWidget->ActivateAllCrosshairs(true); } } void QmitkMxNMultiWidgetEditor::PartClosed(const berry::IWorkbenchPartReference::Pointer& partRef) { if (partRef->GetId() == QmitkMxNMultiWidgetEditor::EDITOR_ID) { m_Impl->m_MxNMultiWidget->ActivateAllCrosshairs(false); } } QmitkMxNMultiWidget* QmitkMxNMultiWidgetEditor::GetMxNMultiWidget() { return m_Impl->m_MxNMultiWidget; } void QmitkMxNMultiWidgetEditor::OnLayoutSet(int row, int column) { m_Impl->m_MxNMultiWidget->ResetLayout(row, column); m_Impl->m_MxNMultiWidget->ActivateAllCrosshairs(true); FirePropertyChange(berry::IWorkbenchPartConstants::PROP_INPUT); } void QmitkMxNMultiWidgetEditor::OnSynchronize(bool synchronized) { m_Impl->m_MxNMultiWidget->Synchronize(synchronized); } +void QmitkMxNMultiWidgetEditor::OnInteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme) +{ + m_Impl->m_MxNMultiWidget->SetInteractionScheme(scheme); +} + ////////////////////////////////////////////////////////////////////////// // PRIVATE ////////////////////////////////////////////////////////////////////////// void QmitkMxNMultiWidgetEditor::SetFocus() { if (nullptr != m_Impl->m_MxNMultiWidget) { m_Impl->m_MxNMultiWidget->setFocus(); } } void QmitkMxNMultiWidgetEditor::CreateQtPartControl(QWidget* parent) { if (nullptr == m_Impl->m_MxNMultiWidget) { QHBoxLayout* layout = new QHBoxLayout(parent); layout->setContentsMargins(0, 0, 0, 0); berry::IBerryPreferences* preferences = dynamic_cast(GetPreferences().GetPointer()); mitk::BaseRenderer::RenderingMode::Type renderingMode = static_cast(preferences->GetInt("Rendering Mode", 0)); m_Impl->m_MxNMultiWidget = new QmitkMxNMultiWidget(parent, 0, 0, renderingMode); - // create left toolbar: interaction scheme toolbar to switch how the render window navigation behaves + // create left toolbar: interaction scheme toolbar to switch how the render window navigation behaves in PACS mode if (nullptr == m_Impl->m_InteractionSchemeToolBar) { m_Impl->m_InteractionSchemeToolBar = new QmitkInteractionSchemeToolBar(parent); layout->addWidget(m_Impl->m_InteractionSchemeToolBar); } m_Impl->m_InteractionSchemeToolBar->SetInteractionEventHandler(m_Impl->m_MxNMultiWidget->GetInteractionEventHandler()); + // show / hide PACS mouse mode interaction scheme toolbar + bool PACSInteractionScheme = preferences->GetBool("PACS like mouse interaction", false); + m_Impl->m_InteractionSchemeToolBar->setVisible(PACSInteractionScheme); + // add center widget: the mxn multi widget layout->addWidget(m_Impl->m_MxNMultiWidget); m_Impl->m_MxNMultiWidget->SetDataStorage(GetDataStorage()); m_Impl->m_MxNMultiWidget->InitializeRenderWindowWidgets(); // create right toolbar: configuration toolbar to change the render window widget layout if (nullptr == m_Impl->m_ConfigurationToolBar) { m_Impl->m_ConfigurationToolBar = new QmitkMultiWidgetConfigurationToolBar(); layout->addWidget(m_Impl->m_ConfigurationToolBar); } connect(m_Impl->m_ConfigurationToolBar, &QmitkMultiWidgetConfigurationToolBar::LayoutSet, this, &QmitkMxNMultiWidgetEditor::OnLayoutSet); connect(m_Impl->m_ConfigurationToolBar, &QmitkMultiWidgetConfigurationToolBar::Synchronized, this, &QmitkMxNMultiWidgetEditor::OnSynchronize); m_Impl->m_MultiWidgetDecorationManager = std::make_unique(m_Impl->m_MxNMultiWidget); GetSite()->GetPage()->AddPartListener(this); OnPreferencesChanged(preferences); } } void QmitkMxNMultiWidgetEditor::OnPreferencesChanged(const berry::IBerryPreferences* preferences) { if (m_Impl->m_MxNMultiWidget->GetRenderWindowWidgets().empty()) { return; } // update decoration preferences m_Impl->m_MultiWidgetDecorationManager->DecorationPreferencesChanged(preferences); // zooming and panning preferences bool constrainedZooming = preferences->GetBool("Use constrained zooming and panning", true); mitk::RenderingManager::GetInstance()->SetConstrainedPanningZooming(constrainedZooming); + bool PACSInteractionScheme = preferences->GetBool("PACS like mouse interaction", false); + OnInteractionSchemeChanged(PACSInteractionScheme ? + mitk::InteractionSchemeSwitcher::PACSStandard : + mitk::InteractionSchemeSwitcher::MITKStandard); + + m_Impl->m_InteractionSchemeToolBar->setVisible(PACSInteractionScheme); + mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(GetDataStorage()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } diff --git a/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.h b/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.h index ea9db18593..08b617db8d 100644 --- a/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.h +++ b/Plugins/org.mitk.gui.qt.mxnmultiwidgeteditor/src/QmitkMxNMultiWidgetEditor.h @@ -1,118 +1,121 @@ /*=================================================================== 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. ===================================================================*/ #ifndef QMITKMXNMULTIWIDGETEDITOR_H #define QMITKMXNMULTIWIDGETEDITOR_H #include #include #include // berry #include +#include + #include class QmitkMxNMultiWidget; class MXNMULTIWIDGETEDITOR_EXPORT QmitkMxNMultiWidgetEditor final : public QmitkAbstractRenderEditor, public berry::IPartListener { Q_OBJECT public: berryObjectMacro(QmitkMxNMultiWidgetEditor) static const QString EDITOR_ID; QmitkMxNMultiWidgetEditor(); virtual ~QmitkMxNMultiWidgetEditor(); /** * @brief Overridden from QmitkAbstractRenderEditor : IRenderWindowPart */ virtual QmitkRenderWindow* GetActiveQmitkRenderWindow() const override; /** * @brief Overridden from QmitkAbstractRenderEditor : IRenderWindowPart */ virtual QHash GetQmitkRenderWindows() const override; /** * @brief Overridden from QmitkAbstractRenderEditor : IRenderWindowPart */ virtual QmitkRenderWindow* GetQmitkRenderWindow(const QString& id) const override; /** * @brief Overridden from QmitkAbstractRenderEditor : IRenderWindowPart */ virtual mitk::Point3D GetSelectedPosition(const QString& id = QString()) const override; /** * @brief Overridden from QmitkAbstractRenderEditor : IRenderWindowPart */ virtual void SetSelectedPosition(const mitk::Point3D& pos, const QString& id = QString()) override; /** * @brief Overridden from QmitkAbstractRenderEditor : IRenderWindowPart */ virtual void EnableDecorations(bool enable, const QStringList& decorations = QStringList()) override; /** * @brief Overridden from QmitkAbstractRenderEditor : IRenderWindowPart */ virtual bool IsDecorationEnabled(const QString& decoration) const override; /** * @brief Overridden from QmitkAbstractRenderEditor : IRenderWindowPart */ virtual QStringList GetDecorations() const override; /** * @brief Overridden from berry::IPartListener */ berry::IPartListener::Events::Types GetPartEventTypes() const override; /** * @brief Overridden from berry::IPartListener */ void PartOpened(const berry::IWorkbenchPartReference::Pointer& partRef) override; /** * @brief Overridden from berry::IPartListener */ void PartClosed(const berry::IWorkbenchPartReference::Pointer& partRef) override; /** * @brief Return the current MxN multi widget of this editor. */ QmitkMxNMultiWidget* GetMxNMultiWidget(); private Q_SLOTS: void OnLayoutSet(int row, int column); void OnSynchronize(bool synchronized); + void OnInteractionSchemeChanged(mitk::InteractionSchemeSwitcher::InteractionScheme scheme); private: /** * @brief Overridden from QmitkAbstractRenderEditor */ virtual void SetFocus() override; /** * @brief Overridden from QmitkAbstractRenderEditor */ virtual void CreateQtPartControl(QWidget* parent) override; /** * @brief Overridden from QmitkAbstractRenderEditor */ virtual void OnPreferencesChanged(const berry::IBerryPreferences* preferences) override; class Impl; const std::unique_ptr m_Impl; }; #endif // QMITKMXNMULTIWIDGETEDITOR_H