diff --git a/Modules/Overlays/QmitkOverlayController.cpp b/Modules/Overlays/QmitkOverlayController.cpp index e821cdd43f..b262205f6f 100644 --- a/Modules/Overlays/QmitkOverlayController.cpp +++ b/Modules/Overlays/QmitkOverlayController.cpp @@ -1,403 +1,406 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkOverlayController.h" #include "QmitkRenderWindow.h" #include "QmitkOverlay.h" #include #include #include QmitkOverlayController::QmitkOverlayController( QmitkRenderWindow* rw, mitk::PropertyList* pl ) : QObject(), m_RenderWindow( rw ), m_PropertyList( pl ) { if ( m_RenderWindow == NULL ) { MITK_ERROR << "invalid QmitkRenderWindow"; return; } connect( rw, SIGNAL( moved() ), this, SLOT( AdjustOverlayPosition() ) ); this->InitializeOverlayLayout(); this->AdjustOverlayPosition(); this->SetOverlayVisibility( true ); if ( m_PropertyList.IsNull() ) m_PropertyList = mitk::PropertyList::New(); } QmitkOverlayController::~QmitkOverlayController() { } void QmitkOverlayController::InitializeOverlayLayout() { // setup widget for each position this->InitializeWidget( QmitkOverlay::top_Left ); this->InitializeWidget( QmitkOverlay::top_Center ); this->InitializeWidget( QmitkOverlay::top_Right ); this->InitializeWidget( QmitkOverlay::middle_Left ); this->InitializeWidget( QmitkOverlay::middle_Right ); this->InitializeWidget( QmitkOverlay::bottom_Left ); this->InitializeWidget( QmitkOverlay::bottom_Center ); this->InitializeWidget( QmitkOverlay::bottom_Right ); } void QmitkOverlayController::InitializeWidget( QmitkOverlay::DisplayPosition pos ) { // create a new QWidget as Tool & FramelessWindowHint m_PositionedOverlays[ pos ] = new QWidget( m_RenderWindow, Qt::Tool | Qt::FramelessWindowHint ); // autoFillBackGround(false) and WA_TranslucentBackground = true are needed to have a translucent background // transparency does NOT work under Win-XP 32-Bit --> paint black background #if !defined(_WIN32) || defined(_WIN64) m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_TranslucentBackground, true ); #else m_PositionedOverlays[ pos ]->setStyleSheet( "QWidget { background: black }" ); m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_TranslucentBackground, false ); #endif // X11 specific attributes m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_X11NetWmWindowTypeUtility, true ); // mac-specific attributes: // making sure overlays are even visible if RenderWindow does not have the focus (not default for Qt::Tool on mac) m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_MacAlwaysShowToolWindow, true ); // testing something m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_MacShowFocusRect, false ); // overlays should not get the focus m_PositionedOverlays[ pos ]->setFocusPolicy( Qt::NoFocus ); // setting the color of the background to transparent - not sure it's needed after the attributes have been set above QPalette p = QPalette(); p.setColor( QPalette::Window, Qt::transparent ); m_PositionedOverlays[ pos ]->setPalette( p ); // setting position-specific properties switch ( pos ) { case QmitkOverlay::top_Left : { // adding left-aligned top-to-bottom layout QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] ); layout->setDirection( QBoxLayout::TopToBottom ); layout->setAlignment( Qt::AlignLeft ); m_PositionedOverlays[ pos ]->layout()->setSpacing( 0 ); break; } case QmitkOverlay::top_Center : { // adding center-aligned top-to-bottom layout QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] ); layout->setDirection( QBoxLayout::TopToBottom ); layout->setAlignment( Qt::AlignCenter ); layout->setAlignment( Qt::AlignLeft ); m_PositionedOverlays[ pos ]->layout()->setSpacing( 0 ); break; } case QmitkOverlay::top_Right : { // adding right-aligned top-to-bottom layout QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] ); layout->setDirection( QBoxLayout::TopToBottom ); layout->setAlignment( Qt::AlignRight ); m_PositionedOverlays[ pos ]->layout()->setSpacing( 0 ); break; } case QmitkOverlay::middle_Left : { // adding left-aligned left-to-right layout QHBoxLayout* layout = new QHBoxLayout( m_PositionedOverlays[ pos ] ); layout->setDirection( QBoxLayout::LeftToRight ); layout->setAlignment( Qt::AlignLeft ); layout->setSpacing( 3 ); break; } case QmitkOverlay::middle_Right : { // adding right-aligned right-to-left layout QHBoxLayout* layout = new QHBoxLayout( m_PositionedOverlays[ pos ] ); layout->setDirection( QBoxLayout::RightToLeft ); layout->setAlignment( Qt::AlignRight ); layout->setSpacing( 3 ); break; } case QmitkOverlay::bottom_Left : { // adding left-aligned bottom-to-top layout QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] ); layout->setDirection( QBoxLayout::BottomToTop ); layout->setAlignment( Qt::AlignLeft ); m_PositionedOverlays[ pos ]->layout()->setSpacing( 0 ); break; } case QmitkOverlay::bottom_Center : { QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] ); layout->setDirection( QBoxLayout::BottomToTop ); layout->setAlignment( Qt::AlignCenter ); m_PositionedOverlays[ pos ]->layout()->setSpacing( 0 ); break; } case QmitkOverlay::bottom_Right : { QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] ); layout->setDirection( QBoxLayout::BottomToTop ); layout->setAlignment( Qt::AlignRight ); m_PositionedOverlays[ pos ]->layout()->setSpacing( 0 ); break; } } } void QmitkOverlayController::AdjustOverlayPosition() { QWidget* widget; QPoint pos; // setting position of top-left overlay-container pos = m_RenderWindow->mapToGlobal( QPoint(0,0) ); m_PositionedOverlays[ QmitkOverlay::top_Left ]->move( pos.x(), pos.y() ); // setting position of top-center overlay-container widget = m_PositionedOverlays[ QmitkOverlay::top_Center ]; pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width()/2, 0 ) ) ; widget->move( pos.x() - widget->size().width()/2, pos.y() ); // setting position of top-right overlay-container widget = m_PositionedOverlays[ QmitkOverlay::top_Right ]; pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width(), 0 ) ) ; widget->move( pos.x() - widget->size().width(), pos.y() ); // setting position of middle-left overlay-container widget = m_PositionedOverlays[ QmitkOverlay::middle_Left ]; pos = m_RenderWindow->mapToGlobal( QPoint( 0, m_RenderWindow->size().height()/2 ) ) ; widget->move( pos.x(), pos.y() - widget->size().height()/2 ); // setting position of middle-right overlay-container widget = m_PositionedOverlays[ QmitkOverlay::middle_Right ]; pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width(), m_RenderWindow->size().height()/2 ) ) ; widget->move( pos.x() - widget->size().width(), pos.y() - widget->size().height()/2 ); // setting position of bottom-left overlay-container widget = m_PositionedOverlays[ QmitkOverlay::bottom_Left ]; pos = m_RenderWindow->mapToGlobal( QPoint( 0, m_RenderWindow->size().height() ) ) ; widget->move( pos.x(), pos.y() - widget->size().height() ); // setting position of bottom-center overlay-container widget = m_PositionedOverlays[ QmitkOverlay::bottom_Center ]; pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width()/2, m_RenderWindow->size().height() ) ) ; widget->move( pos.x() - widget->size().width()/2, pos.y() - widget->size().height() ); // setting position of bottom-right overlay-container widget = m_PositionedOverlays[ QmitkOverlay::bottom_Right ]; pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width(), m_RenderWindow->size().height() ) ) ; widget->move( pos.x() - widget->size().width(), pos.y() - widget->size().height() ); } void QmitkOverlayController::SetOverlayVisibility( bool visible ) { OverlayPositionMap::iterator overlayIter; for ( overlayIter=m_PositionedOverlays.begin(); overlayIter!=m_PositionedOverlays.end(); overlayIter++ ) { if ( visible ) { (overlayIter->second)->show(); } else { (overlayIter->second)->hide(); } } OverlayVector::iterator allOverlaysIter; for( allOverlaysIter=m_AllOverlays.begin(); allOverlaysIter!=m_AllOverlays.end(); allOverlaysIter++ ) { if ( visible ) { (*allOverlaysIter)->GetWidget()->show(); } else { (*allOverlaysIter)->GetWidget()->hide(); } } } void QmitkOverlayController::AddOverlay( QmitkOverlay* overlay ) { // if no renderwindow has been set, it's not possible to add overlays... if ( m_RenderWindow == NULL ) { MITK_ERROR << "invalid QmitkRenderWindow"; return; } if ( overlay != NULL ) { // get desired position and layer of the overlay QmitkOverlay::DisplayPosition pos = overlay->GetPosition(); // concatenate local propertyList and propertyList of the RenderingManager // local properties have priority as they are not overwritten if preset in both m_PropertyList->ConcatenatePropertyList( m_RenderWindow->GetRenderer()->GetRenderingManager()->GetPropertyList(), false ); // add the overlay to the OverlayContainer in the RenderWindow ... overlay->GetWidget()->setParent( m_PositionedOverlays[ pos ] ); // ... and set it up with the correct properties this->UpdateOverlayData( overlay ); // add overlay to list of all overlays and correctly put it into the layering m_AllOverlays.push_back( overlay ); this->RestackOverlays( pos ); // ... and reset the position of the widgets this->AdjustOverlayPosition(); } } void QmitkOverlayController::UpdateOverlayData( QmitkOverlay* overlay ) { - overlay->GenerateData( m_PropertyList ); + if ( overlay != NULL) + { + overlay->GenerateData( m_PropertyList ); + } } void QmitkOverlayController::RemoveOverlay( QmitkOverlay* overlay ) { if ( overlay != NULL ) { // get desired position and layer of the overlay QmitkOverlay::DisplayPosition pos = overlay->GetPosition(); OverlayVector::iterator iter = std::find( m_AllOverlays.begin(), m_AllOverlays.end(), overlay ); if ( iter != m_AllOverlays.end() ) { m_AllOverlays.erase( iter ); overlay->GetWidget()->setParent( NULL ); overlay->GetWidget()->hide(); if ( m_PositionedOverlays[ pos ]->layout()->isEmpty() ) { m_PositionedOverlays[ pos ]->hide(); } else { this->RestackOverlays( pos ); // reset the position of the widgets this->AdjustOverlayPosition(); } } overlay->deleteLater(); } } void QmitkOverlayController::AlignOverlays() { //OverlayVector::iterator overlayIter; //for ( overlayIter=m_AllOverlays.begin(); overlayIter!=m_AllOverlays.end(); overlayIter++ ) //{ // int stackLayer = dynamic_cast( m_PositionedOverlays[ (*overlayIter)->GetPosition() ]->layout() )->isEmpty() ? 0 : layer; // dynamic_cast( m_PositionedOverlays[ (*overlayIter)->GetPosition() ]->layout() )->addWidget( (*overlayIter)->GetWidget(), stackLayer, Qt::AlignLeft ); //} } void QmitkOverlayController::RestackOverlays( QmitkOverlay::DisplayPosition pos ) { OverlayVector::iterator overlayIter; QBoxLayout* layout = dynamic_cast( m_PositionedOverlays[ pos ]->layout() ); std::sort( m_AllOverlays.begin(), m_AllOverlays.end() ); for ( overlayIter=m_AllOverlays.begin(); overlayIter!=m_AllOverlays.end(); overlayIter++ ) { // do nothing if the overlay is not in the right position if ( (*overlayIter)->GetPosition() != pos ) { continue; } // determine the desired stacking layer // if the overlay-container is empty, simply append the overlay to the list // if it's not empty, use the layer of the overlay unsigned int layer = (*overlayIter)->GetLayer(); int stackLayer = 0; if ( !layout->isEmpty() ) { stackLayer = layer; } switch ( pos ) { // same alignment for all lefts, ... case QmitkOverlay::top_Left : {} case QmitkOverlay::middle_Left : {} case QmitkOverlay::bottom_Left : { layout->insertWidget( stackLayer, (*overlayIter)->GetWidget(), 0, Qt::AlignLeft ); break; } // ... for all centers, ... case QmitkOverlay::top_Center : {} case QmitkOverlay::bottom_Center : { layout->insertWidget( stackLayer, (*overlayIter)->GetWidget(), 0, Qt::AlignCenter ); break; } // ... and for all rights case QmitkOverlay::top_Right : {} case QmitkOverlay::middle_Right : {} case QmitkOverlay::bottom_Right : { layout->insertWidget( stackLayer, (*overlayIter)->GetWidget(), 0, Qt::AlignRight ); break; } } } } void QmitkOverlayController::UpdateAllOverlays() { foreach( QmitkOverlay* overlay, m_AllOverlays ) { this->UpdateOverlayData( overlay ); } } diff --git a/Modules/Overlays/QmitkScalarBarOverlay.cpp b/Modules/Overlays/QmitkScalarBarOverlay.cpp index 954d75681c..3e5dd4f2ed 100644 --- a/Modules/Overlays/QmitkScalarBarOverlay.cpp +++ b/Modules/Overlays/QmitkScalarBarOverlay.cpp @@ -1,121 +1,126 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkScalarBarOverlay.h" #include "mitkProperties.h" #include "mitkColorProperty.h" #include "mitkPropertyList.h" #include #include QmitkScalarBarOverlay::QmitkScalarBarOverlay( const char* id ) :QmitkOverlay(id) , m_ScalarBar( NULL ) , m_ObserverTag(0) { m_Widget = m_ScalarBar = new QmitkScalarBar(); QmitkOverlay::AddDropShadow( m_ScalarBar ); } QmitkScalarBarOverlay::~QmitkScalarBarOverlay() { m_PropertyList->GetProperty( m_Id )->RemoveObserver(m_ObserverTag); + m_PropertyList = NULL; } void QmitkScalarBarOverlay::GenerateData( mitk::PropertyList::Pointer pl ) { if ( pl.IsNull() ) return; - m_PropertyList = pl; + m_PropertyList = pl->Clone(); if ( m_PropertyList.IsNotNull() ) { this->SetupCallback( m_PropertyList->GetProperty( m_Id ) ); this->GetProperties( pl ); this->SetScaleFactor(); } else { MITK_DEBUG << "invalid propList"; } } void QmitkScalarBarOverlay::SetScaleFactor() { float scale = 2; if ( m_PropertyList.IsNull() || !m_PropertyList->GetFloatProperty( m_Id, scale ) ) { MITK_DEBUG << "Property " << m_Id << " could not be found"; } - m_ScalarBar->SetScaleFactor( scale ); + + if ( m_ScalarBar != NULL ) + { + m_ScalarBar->SetScaleFactor( scale ); + } } void QmitkScalarBarOverlay::GetProperties( mitk::PropertyList::Pointer pl ) { if ( pl.IsNull() ) return; QPen pen = QPen(); mitk::PropertyList::Pointer propertyList = pl; QPalette palette = QPalette(); // get the desired color of the textOverlays mitk::ColorProperty::Pointer colorProp = dynamic_cast( propertyList->GetProperty( "overlay.color" ) ); if ( colorProp.IsNull() ) { MITK_DEBUG << "creating new colorProperty"; colorProp = mitk::ColorProperty::New( 127.0, 196.0, 232.0 ); } mitk::Color color = colorProp->GetColor(); pen.setColor( QColor( color[0],color[1],color[2],255 ) ); pen.setStyle( Qt::SolidLine ); pen.setCapStyle( Qt::FlatCap ); pen.setJoinStyle( Qt::MiterJoin ); m_ScalarBar->SetPen( pen ); } void QmitkScalarBarOverlay::SetupCallback( mitk::BaseProperty::Pointer prop ) { if ( prop.IsNotNull() ) { prop->RemoveObserver(m_ObserverTag); typedef itk::SimpleMemberCommand< QmitkScalarBarOverlay > MemberCommandType; MemberCommandType::Pointer propModifiedCommand; propModifiedCommand = MemberCommandType::New(); propModifiedCommand->SetCallbackFunction( this, &QmitkScalarBarOverlay::SetScaleFactor ); m_ObserverTag = prop->AddObserver( itk::ModifiedEvent(), propModifiedCommand ); } else { MITK_DEBUG << "invalid property"; } }