diff --git a/Modules/QtWidgets/src/QmitkRenderWindowMenu.cpp b/Modules/QtWidgets/src/QmitkRenderWindowMenu.cpp index 540ebeaa76..a30529f10d 100644 --- a/Modules/QtWidgets/src/QmitkRenderWindowMenu.cpp +++ b/Modules/QtWidgets/src/QmitkRenderWindowMenu.cpp @@ -1,650 +1,648 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkRenderWindowMenu.h" // mitk core #include "mitkProperties.h" #include "mitkResliceMethodProperty.h" // qt #include #include #include #include #include #include #include #include #include //#include"iconClose.xpm" #include "iconCrosshairMode.xpm" #include "iconFullScreen.xpm" //#include"iconHoriSplit.xpm" #include "iconSettings.xpm" //#include"iconVertiSplit.xpm" #include "iconLeaveFullScreen.xpm" // c++ #include unsigned int QmitkRenderWindowMenu::m_DefaultThickMode(1); #ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU QmitkRenderWindowMenu::QmitkRenderWindowMenu(QWidget* parent, Qt::WindowFlags, mitk::BaseRenderer* baseRenderer) : QWidget(nullptr, Qt::Tool | Qt::FramelessWindowHint) #else QmitkRenderWindowMenu::QmitkRenderWindowMenu(QWidget* parent, Qt::WindowFlags flags, mitk::BaseRenderer* baseRenderer) : QWidget(parent, flags) #endif , m_LayoutActionsMenu(nullptr) , m_CrosshairMenu(nullptr) , m_FullScreenMode(false) , m_Renderer(baseRenderer) , m_Parent(parent) , m_CrosshairRotationMode(0) , m_CrosshairVisibility(true) , m_Layout(LayoutIndex::AXIAL) , m_LayoutDesign(LayoutDesign::DEFAULT) , m_OldLayoutDesign(LayoutDesign::DEFAULT) { CreateMenuWidget(); setMinimumWidth(61); // DIRTY.. If you add or remove a button, you need to change the size. setMaximumWidth(61); setAutoFillBackground(true); // Else part fixes the render window menu issue on Linux bug but caused bugs on macOS and Windows // for macOS see bug 3192 // for Windows see bug 12130 //... so macOS and Windows must be treated differently: #if defined(Q_OS_MAC) this->show(); this->setWindowOpacity(0.0f); #else this->setVisible(false); #endif m_AutoRotationTimer = new QTimer(this); m_AutoRotationTimer->setInterval(75); m_HideTimer = new QTimer(this); m_HideTimer->setSingleShot(true); connect(m_AutoRotationTimer, &QTimer::timeout, this, &QmitkRenderWindowMenu::AutoRotateNextStep); connect(m_HideTimer, &QTimer::timeout, this, &QmitkRenderWindowMenu::DeferredHideMenu); connect(m_Parent, &QObject::destroyed, this, &QmitkRenderWindowMenu::deleteLater); } QmitkRenderWindowMenu::~QmitkRenderWindowMenu() { if (m_AutoRotationTimer->isActive()) { m_AutoRotationTimer->stop(); } } void QmitkRenderWindowMenu::SetLayoutIndex(LayoutIndex layoutIndex) { m_Layout = layoutIndex; } void QmitkRenderWindowMenu::UpdateLayoutDesignList(LayoutDesign layoutDesign) { m_LayoutDesign = layoutDesign; if (nullptr == m_LayoutActionsMenu) { CreateSettingsWidget(); } m_DefaultLayoutAction->setEnabled(true); m_All2DTop3DBottomLayoutAction->setEnabled(true); m_All2DLeft3DRightLayoutAction->setEnabled(true); m_OneBigLayoutAction->setEnabled(true); m_Only2DHorizontalLayoutAction->setEnabled(true); m_Only2DVerticalLayoutAction->setEnabled(true); m_OneTop3DBottomLayoutAction->setEnabled(true); m_OneLeft3DRightLayoutAction->setEnabled(true); m_AllHorizontalLayoutAction->setEnabled(true); m_AllVerticalLayoutAction->setEnabled(true); m_RemoveOneLayoutAction->setEnabled(true); switch (m_LayoutDesign) { case LayoutDesign::DEFAULT: { m_DefaultLayoutAction->setEnabled(false); break; } case LayoutDesign::ALL_2D_TOP_3D_BOTTOM: { m_All2DTop3DBottomLayoutAction->setEnabled(false); break; } case LayoutDesign::ALL_2D_LEFT_3D_RIGHT: { m_All2DLeft3DRightLayoutAction->setEnabled(false); break; } case LayoutDesign::ONE_BIG: { m_OneBigLayoutAction->setEnabled(false); break; } case LayoutDesign::ONLY_2D_HORIZONTAL: { m_Only2DHorizontalLayoutAction->setEnabled(false); break; } case LayoutDesign::ONLY_2D_VERTICAL: { m_Only2DVerticalLayoutAction->setEnabled(false); break; } case LayoutDesign::ONE_TOP_3D_BOTTOM: { m_OneTop3DBottomLayoutAction->setEnabled(false); break; } case LayoutDesign::ONE_LEFT_3D_RIGHT: { m_OneLeft3DRightLayoutAction->setEnabled(false); break; } case LayoutDesign::ALL_HORIZONTAL: { m_AllHorizontalLayoutAction->setEnabled(false); break; } case LayoutDesign::ALL_VERTICAL: { m_AllVerticalLayoutAction->setEnabled(false); break; } case LayoutDesign::REMOVE_ONE: { m_RemoveOneLayoutAction->setEnabled(false); break; } case LayoutDesign::NONE: { break; } } } #ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU void QmitkRenderWindowMenu::MoveWidgetToCorrectPos(float opacity) #else void QmitkRenderWindowMenu::MoveWidgetToCorrectPos(float /*opacity*/) #endif { #ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU int X = floor(double(this->m_Parent->width() - this->width() - 8.0)); int Y = 7; QPoint pos = this->m_Parent->mapToGlobal(QPoint(0, 0)); this->move(X + pos.x(), Y + pos.y()); if (opacity < 0) opacity = 0; else if (opacity > 1) opacity = 1; this->setWindowOpacity(opacity); #else int moveX = floor(double(this->m_Parent->width() - this->width() - 4.0)); this->move(moveX, 3); this->show(); #endif } void QmitkRenderWindowMenu::ShowMenu() { MITK_DEBUG << "menu showMenu"; DeferredShowMenu(); } void QmitkRenderWindowMenu::HideMenu() { MITK_DEBUG << "menu hideEvent"; DeferredHideMenu(); } void QmitkRenderWindowMenu::paintEvent(QPaintEvent * /*e*/) { QPainter painter(this); QColor semiTransparentColor = Qt::black; semiTransparentColor.setAlpha(255); painter.fillRect(rect(), semiTransparentColor); } void QmitkRenderWindowMenu::CreateMenuWidget() { QHBoxLayout *layout = new QHBoxLayout(this); layout->setAlignment(Qt::AlignRight); layout->setContentsMargins(1, 1, 1, 1); QSize size(13, 13); m_CrosshairMenu = new QMenu(this); connect(m_CrosshairMenu, &QMenu::aboutToShow, this, &QmitkRenderWindowMenu::OnCrosshairMenuAboutToShow); m_CrosshairModeButton = new QToolButton(this); m_CrosshairModeButton->setMaximumSize(15, 15); m_CrosshairModeButton->setIconSize(size); m_CrosshairModeButton->setMenu(m_CrosshairMenu); m_CrosshairModeButton->setIcon(QIcon(QPixmap(iconCrosshairMode_xpm))); m_CrosshairModeButton->setPopupMode(QToolButton::InstantPopup); - m_CrosshairModeButton->setStyleSheet("QToolButton::menu-indicator { image: none; } border: 0"); + m_CrosshairModeButton->setStyleSheet("QToolButton::menu-indicator { image: none; }"); m_CrosshairModeButton->setAutoRaise(true); layout->addWidget(m_CrosshairModeButton); m_FullScreenButton = new QToolButton(this); m_FullScreenButton->setMaximumSize(15, 15); m_FullScreenButton->setIconSize(size); m_FullScreenButton->setIcon(QIcon(QPixmap(iconFullScreen_xpm))); - m_FullScreenButton->setStyleSheet("border: 0"); m_FullScreenButton->setAutoRaise(true); layout->addWidget(m_FullScreenButton); m_LayoutDesignButton = new QToolButton(this); m_LayoutDesignButton->setMaximumSize(15, 15); m_LayoutDesignButton->setIconSize(size); m_LayoutDesignButton->setIcon(QIcon(QPixmap(iconSettings_xpm))); - m_LayoutDesignButton->setStyleSheet("border: 0"); m_LayoutDesignButton->setAutoRaise(true); layout->addWidget(m_LayoutDesignButton); connect(m_FullScreenButton, &QToolButton::clicked, this, &QmitkRenderWindowMenu::OnFullScreenButton); connect(m_LayoutDesignButton, &QToolButton::clicked, this, &QmitkRenderWindowMenu::OnLayoutDesignButton); } void QmitkRenderWindowMenu::CreateSettingsWidget() { m_LayoutActionsMenu = new QMenu(this); m_DefaultLayoutAction = new QAction("Standard layout", m_LayoutActionsMenu); m_DefaultLayoutAction->setDisabled(true); m_All2DTop3DBottomLayoutAction = new QAction("All 2D top, 3D bottom", m_LayoutActionsMenu); m_All2DTop3DBottomLayoutAction->setDisabled(false); m_All2DLeft3DRightLayoutAction = new QAction("All 2D left, 3D right", m_LayoutActionsMenu); m_All2DLeft3DRightLayoutAction->setDisabled(false); m_OneBigLayoutAction = new QAction("This big", m_LayoutActionsMenu); m_OneBigLayoutAction->setDisabled(false); m_Only2DHorizontalLayoutAction = new QAction("Only 2D horizontal", m_LayoutActionsMenu); m_Only2DHorizontalLayoutAction->setDisabled(false); m_Only2DVerticalLayoutAction = new QAction("Only 2D vertical", m_LayoutActionsMenu); m_Only2DVerticalLayoutAction->setDisabled(false); m_OneTop3DBottomLayoutAction = new QAction("This top, 3D bottom", m_LayoutActionsMenu); m_OneTop3DBottomLayoutAction->setDisabled(false); m_OneLeft3DRightLayoutAction = new QAction("This left, 3D right", m_LayoutActionsMenu); m_OneLeft3DRightLayoutAction->setDisabled(false); m_AllHorizontalLayoutAction = new QAction("All horizontal", m_LayoutActionsMenu); m_AllHorizontalLayoutAction->setDisabled(false); m_AllVerticalLayoutAction = new QAction("All vertical", m_LayoutActionsMenu); m_AllVerticalLayoutAction->setDisabled(false); m_RemoveOneLayoutAction = new QAction("Remove this", m_LayoutActionsMenu); m_RemoveOneLayoutAction->setDisabled(false); m_LayoutActionsMenu->addAction(m_DefaultLayoutAction); m_LayoutActionsMenu->addAction(m_All2DTop3DBottomLayoutAction); m_LayoutActionsMenu->addAction(m_All2DLeft3DRightLayoutAction); m_LayoutActionsMenu->addAction(m_OneBigLayoutAction); m_LayoutActionsMenu->addAction(m_Only2DHorizontalLayoutAction); m_LayoutActionsMenu->addAction(m_Only2DVerticalLayoutAction); m_LayoutActionsMenu->addAction(m_OneTop3DBottomLayoutAction); m_LayoutActionsMenu->addAction(m_OneLeft3DRightLayoutAction); m_LayoutActionsMenu->addAction(m_AllHorizontalLayoutAction); m_LayoutActionsMenu->addAction(m_AllVerticalLayoutAction); m_LayoutActionsMenu->addAction(m_RemoveOneLayoutAction); m_LayoutActionsMenu->setVisible(false); connect(m_DefaultLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::DEFAULT); }); connect(m_All2DTop3DBottomLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ALL_2D_TOP_3D_BOTTOM); }); connect(m_All2DLeft3DRightLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ALL_2D_LEFT_3D_RIGHT); }); connect(m_OneBigLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ONE_BIG); }); connect(m_Only2DHorizontalLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ONLY_2D_HORIZONTAL); }); connect(m_Only2DVerticalLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ONLY_2D_VERTICAL); }); connect(m_OneTop3DBottomLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ONE_TOP_3D_BOTTOM); }); connect(m_OneLeft3DRightLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ONE_LEFT_3D_RIGHT); }); connect(m_AllHorizontalLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ALL_HORIZONTAL); }); connect(m_AllVerticalLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::ALL_VERTICAL); }); connect(m_RemoveOneLayoutAction, &QAction::triggered, [this]() { this->OnSetLayout(LayoutDesign::REMOVE_ONE); }); } void QmitkRenderWindowMenu::ChangeFullScreenIcon() { m_FullScreenButton->setIcon(m_FullScreenMode ? QPixmap(iconLeaveFullScreen_xpm) : QPixmap(iconFullScreen_xpm)); } void QmitkRenderWindowMenu::DeferredShowMenu() { MITK_DEBUG << "deferred show menu"; m_HideTimer->stop(); // Else part fixes the render window menu issue on Linux bug but caused bugs on macOS and Windows // for macOS see bug 3192 // for Windows see bug 12130 //... so macOS and Windows must be treated differently: #if defined(Q_OS_MAC) this->setWindowOpacity(1.0f); #else this->setVisible(true); this->raise(); #endif } void QmitkRenderWindowMenu::DeferredHideMenu() { MITK_DEBUG << "menu deferredhidemenu"; // Else part fixes the render window menu issue on Linux bug but caused bugs on macOS and Windows // for macOS see bug 3192 // for Windows see bug 12130 //... so macOS and Windows must be treated differently: #if defined(Q_OS_MAC) this->setWindowOpacity(0.0f); #else this->setVisible(false); #endif } void QmitkRenderWindowMenu::smoothHide() { MITK_DEBUG << "menu leaveEvent"; m_HideTimer->start(10); } void QmitkRenderWindowMenu::enterEvent(QEvent * /*e*/) { MITK_DEBUG << "menu enterEvent"; DeferredShowMenu(); } void QmitkRenderWindowMenu::leaveEvent(QEvent * /*e*/) { MITK_DEBUG << "menu leaveEvent"; smoothHide(); } void QmitkRenderWindowMenu::AutoRotateNextStep() { if (m_Renderer->GetCameraRotationController()) { m_Renderer->GetCameraRotationController()->GetSlice()->Next(); } } void QmitkRenderWindowMenu::OnAutoRotationActionTriggered() { if (m_AutoRotationTimer->isActive()) { m_AutoRotationTimer->stop(); m_Renderer->GetCameraRotationController()->GetSlice()->PingPongOff(); } else { m_Renderer->GetCameraRotationController()->GetSlice()->PingPongOn(); m_AutoRotationTimer->start(); } } void QmitkRenderWindowMenu::OnTSNumChanged(int num) { MITK_DEBUG << "Thickslices num: " << num << " on renderer " << m_Renderer.GetPointer(); if (m_Renderer.IsNotNull()) { unsigned int thickSlicesMode = 0; // determine the state of the thick-slice mode mitk::ResliceMethodProperty *resliceMethodEnumProperty = nullptr; if(m_Renderer->GetCurrentWorldPlaneGeometryNode()->GetProperty(resliceMethodEnumProperty, "reslice.thickslices") && resliceMethodEnumProperty) { thickSlicesMode = resliceMethodEnumProperty->GetValueAsId(); if(thickSlicesMode!=0) m_DefaultThickMode = thickSlicesMode; } if(thickSlicesMode==0 && num>0) //default mode only for single slices { thickSlicesMode = m_DefaultThickMode; //mip default m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty("reslice.thickslices.showarea", mitk::BoolProperty::New(true)); } if(num<1) { thickSlicesMode = 0; m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty("reslice.thickslices.showarea", mitk::BoolProperty::New(false)); } m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty("reslice.thickslices", mitk::ResliceMethodProperty::New(thickSlicesMode)); m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty("reslice.thickslices.num", mitk::IntProperty::New(num)); m_TSLabel->setText(QString::number(num * 2 + 1)); m_Renderer->SendUpdateSlice(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkRenderWindowMenu::OnCrosshairMenuAboutToShow() { QMenu *crosshairModesMenu = m_CrosshairMenu; crosshairModesMenu->clear(); QAction *resetViewAction = new QAction(crosshairModesMenu); resetViewAction->setText("Reset view"); crosshairModesMenu->addAction(resetViewAction); connect(resetViewAction, &QAction::triggered, this, &QmitkRenderWindowMenu::ResetView); // Show hide crosshairs { QAction *showHideCrosshairVisibilityAction = new QAction(crosshairModesMenu); showHideCrosshairVisibilityAction->setText("Show crosshair"); showHideCrosshairVisibilityAction->setCheckable(true); showHideCrosshairVisibilityAction->setChecked(m_CrosshairVisibility); crosshairModesMenu->addAction(showHideCrosshairVisibilityAction); connect(showHideCrosshairVisibilityAction, &QAction::toggled, this, &QmitkRenderWindowMenu::OnCrosshairVisibilityChanged); } // Rotation mode { QAction *rotationGroupSeparator = new QAction(crosshairModesMenu); rotationGroupSeparator->setSeparator(true); rotationGroupSeparator->setText("Rotation mode"); crosshairModesMenu->addAction(rotationGroupSeparator); QActionGroup *rotationModeActionGroup = new QActionGroup(crosshairModesMenu); rotationModeActionGroup->setExclusive(true); QAction *noCrosshairRotation = new QAction(crosshairModesMenu); noCrosshairRotation->setActionGroup(rotationModeActionGroup); noCrosshairRotation->setText("No crosshair rotation"); noCrosshairRotation->setCheckable(true); noCrosshairRotation->setChecked(m_CrosshairRotationMode == 0); noCrosshairRotation->setData(0); crosshairModesMenu->addAction(noCrosshairRotation); QAction *singleCrosshairRotation = new QAction(crosshairModesMenu); singleCrosshairRotation->setActionGroup(rotationModeActionGroup); singleCrosshairRotation->setText("Crosshair rotation"); singleCrosshairRotation->setCheckable(true); singleCrosshairRotation->setChecked(m_CrosshairRotationMode == 1); singleCrosshairRotation->setData(1); crosshairModesMenu->addAction(singleCrosshairRotation); QAction *coupledCrosshairRotation = new QAction(crosshairModesMenu); coupledCrosshairRotation->setActionGroup(rotationModeActionGroup); coupledCrosshairRotation->setText("Coupled crosshair rotation"); coupledCrosshairRotation->setCheckable(true); coupledCrosshairRotation->setChecked(m_CrosshairRotationMode == 2); coupledCrosshairRotation->setData(2); crosshairModesMenu->addAction(coupledCrosshairRotation); QAction *swivelMode = new QAction(crosshairModesMenu); swivelMode->setActionGroup(rotationModeActionGroup); swivelMode->setText("Swivel mode"); swivelMode->setCheckable(true); swivelMode->setChecked(m_CrosshairRotationMode == 3); swivelMode->setData(3); crosshairModesMenu->addAction(swivelMode); connect(rotationModeActionGroup, &QActionGroup::triggered, this, &QmitkRenderWindowMenu::OnCrosshairRotationModeSelected); } // auto rotation support if (m_Renderer.IsNotNull() && m_Renderer->GetMapperID() == mitk::BaseRenderer::Standard3D) { QAction *autoRotationGroupSeparator = new QAction(crosshairModesMenu); autoRotationGroupSeparator->setSeparator(true); crosshairModesMenu->addAction(autoRotationGroupSeparator); QAction *autoRotationAction = crosshairModesMenu->addAction("Auto Rotation"); autoRotationAction->setCheckable(true); autoRotationAction->setChecked(m_AutoRotationTimer->isActive()); connect(autoRotationAction, &QAction::triggered, this, &QmitkRenderWindowMenu::OnAutoRotationActionTriggered); } // Thickslices support if (m_Renderer.IsNotNull() && m_Renderer->GetMapperID() == mitk::BaseRenderer::Standard2D) { QAction *thickSlicesGroupSeparator = new QAction(crosshairModesMenu); thickSlicesGroupSeparator->setSeparator(true); thickSlicesGroupSeparator->setText("ThickSlices mode"); crosshairModesMenu->addAction(thickSlicesGroupSeparator); QActionGroup *thickSlicesActionGroup = new QActionGroup(crosshairModesMenu); thickSlicesActionGroup->setExclusive(true); int currentMode = 0; { mitk::ResliceMethodProperty::Pointer m = dynamic_cast( m_Renderer->GetCurrentWorldPlaneGeometryNode()->GetProperty("reslice.thickslices")); if (m.IsNotNull()) currentMode = m->GetValueAsId(); } int currentNum = 1; { mitk::IntProperty::Pointer m = dynamic_cast( m_Renderer->GetCurrentWorldPlaneGeometryNode()->GetProperty("reslice.thickslices.num")); if (m.IsNotNull()) { currentNum = m->GetValue(); } } if (currentMode == 0) currentNum = 0; QSlider *m_TSSlider = new QSlider(crosshairModesMenu); m_TSSlider->setMinimum(0); m_TSSlider->setMaximum(50); m_TSSlider->setValue(currentNum); m_TSSlider->setOrientation(Qt::Horizontal); connect(m_TSSlider, &QSlider::valueChanged, this, &QmitkRenderWindowMenu::OnTSNumChanged); QHBoxLayout *tsLayout = new QHBoxLayout; tsLayout->setContentsMargins(4, 4, 4, 4); tsLayout->addWidget(new QLabel("TS: ")); tsLayout->addWidget(m_TSSlider); tsLayout->addWidget(m_TSLabel = new QLabel(QString::number(currentNum * 2 + 1), this)); QWidget *tsWidget = new QWidget; tsWidget->setLayout(tsLayout); QWidgetAction *m_TSSliderAction = new QWidgetAction(crosshairModesMenu); m_TSSliderAction->setDefaultWidget(tsWidget); crosshairModesMenu->addAction(m_TSSliderAction); } } void QmitkRenderWindowMenu::OnCrosshairVisibilityChanged(bool visible) { m_CrosshairVisibility = visible; emit CrosshairVisibilityChanged(visible); } void QmitkRenderWindowMenu::OnCrosshairRotationModeSelected(QAction *action) { m_CrosshairRotationMode = action->data().toInt(); emit CrosshairRotationModeChanged(m_CrosshairRotationMode); } void QmitkRenderWindowMenu::OnFullScreenButton(bool /*checked*/) { if (!m_FullScreenMode) { m_FullScreenMode = true; m_OldLayoutDesign = m_LayoutDesign; emit LayoutDesignChanged(LayoutDesign::ONE_BIG); } else { m_FullScreenMode = false; emit LayoutDesignChanged(m_OldLayoutDesign); } MoveWidgetToCorrectPos(1.0f); ChangeFullScreenIcon(); DeferredShowMenu(); } void QmitkRenderWindowMenu::OnLayoutDesignButton(bool /*checked*/) { if (nullptr == m_LayoutActionsMenu) { CreateSettingsWidget(); } QPoint point = mapToGlobal(m_LayoutDesignButton->geometry().topLeft()); m_LayoutActionsMenu->setVisible(true); m_LayoutActionsMenu->exec(point); } void QmitkRenderWindowMenu::OnSetLayout(LayoutDesign layoutDesign) { m_FullScreenMode = false; ChangeFullScreenIcon(); m_LayoutDesign = layoutDesign; emit LayoutDesignChanged(m_LayoutDesign); DeferredShowMenu(); } diff --git a/Modules/QtWidgets/src/QmitkRenderWindowWidget.cpp b/Modules/QtWidgets/src/QmitkRenderWindowWidget.cpp index 2f3fa6fdec..2f50f4351a 100644 --- a/Modules/QtWidgets/src/QmitkRenderWindowWidget.cpp +++ b/Modules/QtWidgets/src/QmitkRenderWindowWidget.cpp @@ -1,254 +1,254 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkRenderWindowWidget.h" // vtk #include #include QmitkRenderWindowWidget::QmitkRenderWindowWidget(QWidget* parent/* = nullptr*/, const QString& widgetName/* = ""*/, mitk::DataStorage* dataStorage/* = nullptr*/) : QFrame(parent) , m_WidgetName(widgetName) , m_DataStorage(dataStorage) , m_RenderWindow(nullptr) , m_PointSetNode(nullptr) , m_PointSet(nullptr) { this->InitializeGUI(); } QmitkRenderWindowWidget::~QmitkRenderWindowWidget() { auto sliceNavigationController = m_RenderWindow->GetSliceNavigationController(); if (nullptr != sliceNavigationController) { sliceNavigationController->SetCrosshairEvent.RemoveListener(mitk::MessageDelegate1(this, &QmitkRenderWindowWidget::SetCrosshair)); } if (nullptr != m_DataStorage) { m_DataStorage->Remove(m_PointSetNode); } } void QmitkRenderWindowWidget::SetDataStorage(mitk::DataStorage* dataStorage) { if (dataStorage == m_DataStorage) { return; } m_DataStorage = dataStorage; if (nullptr != m_RenderWindow) { mitk::BaseRenderer::GetInstance(m_RenderWindow->GetRenderWindow())->SetDataStorage(dataStorage); } } mitk::SliceNavigationController* QmitkRenderWindowWidget::GetSliceNavigationController() const { return m_RenderWindow->GetSliceNavigationController(); } void QmitkRenderWindowWidget::RequestUpdate() { mitk::RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow->GetRenderWindow()); } void QmitkRenderWindowWidget::ForceImmediateUpdate() { mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(m_RenderWindow->GetRenderWindow()); } void QmitkRenderWindowWidget::SetGradientBackgroundColors(const mitk::Color& upper, const mitk::Color& lower) { vtkRenderer* vtkRenderer = m_RenderWindow->GetRenderer()->GetVtkRenderer(); if (nullptr == vtkRenderer) { return; } m_GradientBackgroundColors.first = upper; m_GradientBackgroundColors.second = lower; vtkRenderer->SetBackground(lower[0], lower[1], lower[2]); vtkRenderer->SetBackground2(upper[0], upper[1], upper[2]); ShowGradientBackground(true); } void QmitkRenderWindowWidget::ShowGradientBackground(bool show) { m_RenderWindow->GetRenderer()->GetVtkRenderer()->SetGradientBackground(show); } bool QmitkRenderWindowWidget::IsGradientBackgroundOn() const { return m_RenderWindow->GetRenderer()->GetVtkRenderer()->GetGradientBackground(); } void QmitkRenderWindowWidget::SetDecorationColor(const mitk::Color& color) { m_DecorationColor = color; m_CornerAnnotation->GetTextProperty()->SetColor(m_DecorationColor[0], m_DecorationColor[1], m_DecorationColor[2]); QColor hexColor(m_DecorationColor[0] * 255, m_DecorationColor[1] * 255, m_DecorationColor[2] * 255); - setStyleSheet("border: 2px solid " + hexColor.name(QColor::HexRgb)); + setStyleSheet("QmitkRenderWindowWidget { border: 2px solid " + hexColor.name(QColor::HexRgb) + "; }"); } void QmitkRenderWindowWidget::ShowColoredRectangle(bool show) { if (show) { setFrameStyle(QFrame::Box | QFrame::Plain); } else { setFrameStyle(NoFrame); } } bool QmitkRenderWindowWidget::IsColoredRectangleVisible() const { return frameStyle() > 0; } void QmitkRenderWindowWidget::ShowCornerAnnotation(bool show) { m_CornerAnnotation->SetVisibility(show); } bool QmitkRenderWindowWidget::IsCornerAnnotationVisible() const { return m_CornerAnnotation->GetVisibility() > 0; } void QmitkRenderWindowWidget::SetCornerAnnotationText(const std::string& cornerAnnotation) { m_CornerAnnotation->SetText(0, cornerAnnotation.c_str()); } std::string QmitkRenderWindowWidget::GetCornerAnnotationText() const { return std::string(m_CornerAnnotation->GetText(0)); } bool QmitkRenderWindowWidget::IsRenderWindowMenuActivated() const { return m_RenderWindow->GetActivateMenuWidgetFlag(); } void QmitkRenderWindowWidget::ActivateCrosshair(bool activate) { if (nullptr == m_DataStorage) { return; } if (activate) { try { m_DataStorage->Add(m_PointSetNode); } catch(std::invalid_argument& /*e*/) { // crosshair already existing return; } } else { m_DataStorage->Remove(m_PointSetNode); } } void QmitkRenderWindowWidget::InitializeGUI() { m_Layout = new QHBoxLayout(this); m_Layout->setMargin(0); setLayout(m_Layout); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setContentsMargins(0, 0, 0, 0); if (nullptr == m_DataStorage) { return; } mitk::RenderingManager::GetInstance()->SetDataStorage(m_DataStorage); // create render window for this render window widget m_RenderWindow = new QmitkRenderWindow(this, m_WidgetName, nullptr); m_RenderWindow->SetLayoutIndex(mitk::BaseRenderer::ViewDirection::SAGITTAL); m_RenderWindow->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Sagittal); m_RenderWindow->GetSliceNavigationController()->SetCrosshairEvent.AddListener(mitk::MessageDelegate1(this, &QmitkRenderWindowWidget::SetCrosshair)); connect(m_RenderWindow, &QVTKOpenGLWidget::mouseEvent, this, &QmitkRenderWindowWidget::MouseEvent); mitk::TimeGeometry::ConstPointer timeGeometry = m_DataStorage->ComputeBoundingGeometry3D(m_DataStorage->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(timeGeometry); m_Layout->addWidget(m_RenderWindow); // add point set as a crosshair m_PointSetNode = mitk::DataNode::New(); m_PointSetNode->SetProperty("name", mitk::StringProperty::New("Crosshair of render window " + m_WidgetName.toStdString())); m_PointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true)); // crosshair-node should typically be invisible // set the crosshair only visible for this specific renderer m_PointSetNode->SetBoolProperty("fixedLayer", true, m_RenderWindow->GetRenderer()); m_PointSetNode->SetVisibility(true, m_RenderWindow->GetRenderer()); m_PointSetNode->SetVisibility(false); m_PointSet = mitk::PointSet::New(); m_PointSetNode->SetData(m_PointSet); // set colors and corner annotation InitializeDecorations(); } void QmitkRenderWindowWidget::InitializeDecorations() { vtkRenderer* vtkRenderer = m_RenderWindow->GetRenderer()->GetVtkRenderer(); if (nullptr == vtkRenderer) { return; } // initialize background color gradients float black[3] = { 0.0f, 0.0f, 0.0f }; SetGradientBackgroundColors(black, black); // initialize decoration color, rectangle and annotation text float white[3] = { 1.0f, 1.0f, 1.0f }; m_DecorationColor = white; setFrameStyle(QFrame::Box | QFrame::Plain); QColor hexColor(m_DecorationColor[0] * 255, m_DecorationColor[1] * 255, m_DecorationColor[2] * 255); setStyleSheet("border: 2px solid " + hexColor.name(QColor::HexRgb)); m_CornerAnnotation = vtkSmartPointer::New(); m_CornerAnnotation->SetText(0, "Sagittal"); m_CornerAnnotation->SetMaximumFontSize(12); m_CornerAnnotation->GetTextProperty()->SetColor(m_DecorationColor[0], m_DecorationColor[1], m_DecorationColor[2]); if (0 == vtkRenderer->HasViewProp(m_CornerAnnotation)) { vtkRenderer->AddViewProp(m_CornerAnnotation); } } void QmitkRenderWindowWidget::SetCrosshair(mitk::Point3D selectedPoint) { m_PointSet->SetPoint(1, selectedPoint, 0); mitk::RenderingManager::GetInstance()->RequestUpdate(m_RenderWindow->GetRenderWindow()); }