Commit da13d599 authored by cornimueller's avatar cornimueller
Browse files

[ADD] Added use-count to WQtCustomDockWidgets to save how many modules need a...

[ADD] Added use-count to WQtCustomDockWidgets to save how many modules need a certain widget. A widget is only deleted if it isn't used anymore.
parent 8c327e00
......@@ -100,14 +100,14 @@ public:
virtual boost::signals2::signal1< void, std::string >* getPickSignal() = 0;
/**
* Instruct the MainWindow to create a new custom widget.
* Instruct the MainWindow to open a new custom widget.
*
* \param title the title of the widget
* \param projectionMode the kind of projection which should be used
* \param shutdownCondition condition to wait for the shutdown of a module
* \return the created widget
*/
virtual boost::shared_ptr< WCustomWidget > createCustomWidget( std::string title, WGECamera::ProjectionMode projectionMode,
virtual boost::shared_ptr< WCustomWidget > openCustomWidget( std::string title, WGECamera::ProjectionMode projectionMode,
boost::shared_ptr< WCondition > shutdownCondition ) = 0;
/**
......
......@@ -38,7 +38,7 @@
#include <QtGui/QVBoxLayout>
#include "WMainWindow.h"
#include "WCreateCustomDockWidgetEvent.h"
#include "WOpenCustomDockWidgetEvent.h"
#include "WQtGLWidget.h"
#include "WQtNavGLWidget.h"
#include "WQtCustomDockWidget.h"
......@@ -303,29 +303,33 @@ void WMainWindow::closeEvent( QCloseEvent* e )
void WMainWindow::customEvent( QEvent* event )
{
if( event->type() == WCreateCustomDockWidgetEvent::CUSTOM_TYPE )
if( event->type() == WOpenCustomDockWidgetEvent::CUSTOM_TYPE )
{
// CreateCustomDockWidgetEvent
WCreateCustomDockWidgetEvent* ccdwEvent = static_cast< WCreateCustomDockWidgetEvent* >( event );
std::string title = ccdwEvent->getTitle();
// OpenCustomDockWidgetEvent
WOpenCustomDockWidgetEvent* ocdwEvent = static_cast< WOpenCustomDockWidgetEvent* >( event );
std::string title = ocdwEvent->getTitle();
boost::shared_ptr< WQtCustomDockWidget > widget;
boost::mutex::scoped_lock lock( m_customDockWidgetsLock );
if( m_customDockWidgets.count( title ) == 0 )
{
boost::shared_ptr< WQtCustomDockWidget > widget = boost::shared_ptr< WQtCustomDockWidget >(
new WQtCustomDockWidget( title, this, ccdwEvent->getProjectionMode() ) );
// create new custom dock widget
widget = boost::shared_ptr< WQtCustomDockWidget >(
new WQtCustomDockWidget( title, this, ocdwEvent->getProjectionMode() ) );
addDockWidget( Qt::BottomDockWidgetArea, widget.get() );
// store it in CustomDockWidget list
m_customDockWidgets.insert( make_pair( title, widget ) );
ccdwEvent->getFlag()->set( widget );
}
else
{
ccdwEvent->getFlag()->set( m_customDockWidgets[title] );
widget = m_customDockWidgets[title];
widget->increaseUseCount();
}
m_customDockWidgetsLock.unlock();
ocdwEvent->getFlag()->set( widget );
}
else
{
......@@ -350,9 +354,11 @@ void WMainWindow::closeCustomDockWidget( std::string title )
boost::mutex::scoped_lock lock( m_customDockWidgetsLock );
if( m_customDockWidgets.count( title ) > 0 )
{
m_customDockWidgets[title]->close();
m_customDockWidgets.erase( title );
if( m_customDockWidgets[title]->decreaseUseCount() )
{
// custom dock widget should be deleted
m_customDockWidgets.erase( title );
}
}
m_customDockWidgetsLock.unlock();
}
......
......@@ -147,7 +147,7 @@ protected:
/**
* Handle custom events.
* Currently only WCreateCustomDockWidgetEvent.
* Currently only WOpenCustomDockWidgetEvent.
*
* \param event the custom event
*/
......
......@@ -24,9 +24,9 @@
#include <string>
#include "WCreateCustomDockWidgetEvent.h"
#include "WOpenCustomDockWidgetEvent.h"
WCreateCustomDockWidgetEvent::WCreateCustomDockWidgetEvent( std::string title, WGECamera::ProjectionMode projectionMode,
WOpenCustomDockWidgetEvent::WOpenCustomDockWidgetEvent( std::string title, WGECamera::ProjectionMode projectionMode,
boost::shared_ptr< WFlag< boost::shared_ptr< WCustomWidget > > > flag )
: QEvent( CUSTOM_TYPE ),
m_title( title ),
......@@ -35,17 +35,17 @@ WCreateCustomDockWidgetEvent::WCreateCustomDockWidgetEvent( std::string title, W
{
}
std::string WCreateCustomDockWidgetEvent::getTitle() const
std::string WOpenCustomDockWidgetEvent::getTitle() const
{
return m_title;
}
WGECamera::ProjectionMode WCreateCustomDockWidgetEvent::getProjectionMode() const
WGECamera::ProjectionMode WOpenCustomDockWidgetEvent::getProjectionMode() const
{
return m_projectionMode;
}
boost::shared_ptr< WFlag< boost::shared_ptr< WCustomWidget > > > WCreateCustomDockWidgetEvent::getFlag() const
boost::shared_ptr< WFlag< boost::shared_ptr< WCustomWidget > > > WOpenCustomDockWidgetEvent::getFlag() const
{
return m_flag;
}
......@@ -22,8 +22,8 @@
//
//---------------------------------------------------------------------------
#ifndef WCREATECUSTOMDOCKWIDGETEVENT_H
#define WCREATECUSTOMDOCKWIDGETEVENT_H
#ifndef WOPENCUSTOMDOCKWIDGETEVENT_H
#define WOPENCUSTOMDOCKWIDGETEVENT_H
#include <string>
#include <QtCore/QEvent>
......@@ -33,25 +33,25 @@
#include "../WCustomWidget.h"
/**
* A Qt event to create a new custom dock widget if posted to the WMainWindow.
* A Qt event to open a new custom dock widget if posted to the WMainWindow.
*/
class WCreateCustomDockWidgetEvent : public QEvent
class WOpenCustomDockWidgetEvent : public QEvent
{
public:
/**
* Constructor
*
* \param title the title of the widget to create.
* \param title the title of the widget to open
* \param projectionMode the kind of projection which should be used
* \param flag The WFlag which contains the widget after its creation.
*/
explicit WCreateCustomDockWidgetEvent( std::string title, WGECamera::ProjectionMode projectionMode,
explicit WOpenCustomDockWidgetEvent( std::string title, WGECamera::ProjectionMode projectionMode,
boost::shared_ptr< WFlag< boost::shared_ptr< WCustomWidget > > > flag );
/**
* Get the title of the widget to create.
* Get the title of the widget to open.
*
* \return title of the widget to create
* \return title of the widget to open
*/
std::string getTitle() const;
......@@ -93,4 +93,4 @@ private:
boost::shared_ptr< WFlag< boost::shared_ptr< WCustomWidget > > > m_flag;
};
#endif // WCREATECUSTOMDOCKWIDGETEVENT_H
#endif // WOPENCUSTOMDOCKWIDGETEVENT_H
......@@ -38,7 +38,7 @@
#include "../../kernel/WKernel.h"
#include "../../modules/data/WMData.h"
#include "../../utils/WIOTools.h"
#include "WCreateCustomDockWidgetEvent.h"
#include "WOpenCustomDockWidgetEvent.h"
#include "../../common/WConditionOneShot.h"
#include "WQt4Gui.h"
......@@ -191,12 +191,12 @@ boost::signals2::signal1< void, std::string >* WQt4Gui::getPickSignal()
return m_mainWindow->getPickSignal();
}
boost::shared_ptr< WCustomWidget > WQt4Gui::createCustomWidget( std::string title, WGECamera::ProjectionMode projectionMode,
boost::shared_ptr< WCustomWidget > WQt4Gui::openCustomWidget( std::string title, WGECamera::ProjectionMode projectionMode,
boost::shared_ptr< WCondition > shutdownCondition )
{
boost::shared_ptr< WFlag< boost::shared_ptr< WCustomWidget > > > widgetFlag(
new WFlag< boost::shared_ptr< WCustomWidget > >( new WConditionOneShot, boost::shared_ptr< WCustomWidget >() ) );
QCoreApplication::postEvent( m_mainWindow, new WCreateCustomDockWidgetEvent( title, projectionMode, widgetFlag ) );
QCoreApplication::postEvent( m_mainWindow, new WOpenCustomDockWidgetEvent( title, projectionMode, widgetFlag ) );
WConditionSet conditionSet;
conditionSet.add( widgetFlag->getCondition() );
......
......@@ -98,14 +98,14 @@ public:
boost::signals2::signal1< void, std::string >* getPickSignal();
/**
* Instruct the WMainWindow to create a new custom widget.
* Instruct the WMainWindow to open a new custom widget.
*
* \param title the title of the widget
* \param projectionMode the kind of projection which should be used
* \param shutdownCondition condition to wait for the shutdown of a module
* \return the created widget
*/
virtual boost::shared_ptr< WCustomWidget > createCustomWidget( std::string title, WGECamera::ProjectionMode projectionMode,
virtual boost::shared_ptr< WCustomWidget > openCustomWidget( std::string title, WGECamera::ProjectionMode projectionMode,
boost::shared_ptr< WCondition > shutdownCondition );
/**
......@@ -115,7 +115,6 @@ public:
*/
virtual void closeCustomWidget( std::string title );
protected:
private:
......
......@@ -30,7 +30,8 @@
#include "../../graphicsEngine/WGEViewer.h"
WQtCustomDockWidget::WQtCustomDockWidget( std::string title, QWidget* parent, WGECamera::ProjectionMode projectionMode )
: QDockWidget( QString::fromStdString( title ), parent )
: QDockWidget( QString::fromStdString( title ), parent ),
m_useCount( 1 )
{
// setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
setFeatures( QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
......@@ -48,6 +49,22 @@ osg::ref_ptr< osg::Group > WQtCustomDockWidget::getScene() const
return m_scene;
}
void WQtCustomDockWidget::increaseUseCount()
{
++m_useCount;
}
bool WQtCustomDockWidget::decreaseUseCount()
{
--m_useCount;
bool shouldClose = ( m_useCount == 0 );
if( shouldClose )
{
close();
}
return shouldClose;
}
void WQtCustomDockWidget::closeEvent( QCloseEvent* event )
{
// forward events
......
......@@ -53,6 +53,18 @@ public:
*/
virtual osg::ref_ptr< osg::Group > getScene() const;
/**
* Notify the widget that another module needs it.
*/
void increaseUseCount();
/**
* Notify the widget that it is not needed by one module anymore.
*
* \returns whether the widget is not needed at all and should be deleted
*/
bool decreaseUseCount();
protected:
/**
* Event handler for close events
......@@ -71,6 +83,15 @@ private:
* the scene which is displayed by the GL widget
*/
osg::ref_ptr< osg::Group > m_scene;
/**
* How many modules currently need this widget?
* Widget should be closed if this count reaches 0.
*
* \note It is not thread safe. But concurrent access is prevented by
* WMainWindow's m_customDockWidgetsLock
*/
unsigned int m_useCount;
};
#endif // WQTCUSTOMDOCKWIDGET_H
......@@ -50,7 +50,9 @@
#include "WMEEGView.h"
WMEEGView::WMEEGView()
: WModule()
: WModule(),
m_isActive( new WCondition, true ),
m_wasActive( true )
{
}
......@@ -76,26 +78,42 @@ const std::string WMEEGView::getDescription() const
void WMEEGView::moduleMain()
{
// do initialization
m_widget = WKernel::getRunningKernel()->getGui()->createCustomWidget(
getName(), WGECamera::TWO_D, m_shutdownFlag.getCondition() );
if( m_widget.get() )
{
debugLog() << "Succesfully opened EEG View widget.";
m_node = createText();
m_widget->getScene()->addChild( m_node );
m_moduleState.add( m_isActive.getCondition() );
m_node = createText();
if( openCustomWidget() )
{
// signal ready
ready();
waitForStop();
}
else
{
warnLog() << "Could not create EEG View widget.";
while( !m_shutdownFlag() ) // loop until the module container requests the module to quit
{
bool isActive = m_isActive();
if( isActive != m_wasActive )
{
// "active" property changed
if ( isActive )
{
if( !openCustomWidget() )
{
// Shut down module if widget could not be opened.
m_FinishRequested = true;
m_shutdownFlag.set( true );
}
}
else
{
closeCustomWidget();
}
m_wasActive = isActive;
}
m_moduleState.wait(); // waits for firing of m_moduleState ( dataChanged, shutdown, etc. )
}
}
WKernel::getRunningKernel()->getGui()->closeCustomWidget( getName() );
// This should also delete the scene which was only referenced by this viewer.
// clean up
closeCustomWidget();
}
void WMEEGView::connectors()
......@@ -121,17 +139,7 @@ void WMEEGView::slotPropertyChanged( std::string propertyName )
{
if( propertyName == "active" )
{
if ( m_properties->getValue< bool >( propertyName ) )
{
if( !m_widget->getScene()->containsNode( m_node) )
{
m_widget->getScene()->addChild( m_node );
}
}
else
{
m_widget->getScene()->removeChild( m_node );
}
m_isActive.set( m_properties->getValue< bool >( propertyName ) );
}
else
{
......@@ -141,6 +149,29 @@ void WMEEGView::slotPropertyChanged( std::string propertyName )
}
}
bool WMEEGView::openCustomWidget()
{
m_widget = WKernel::getRunningKernel()->getGui()->openCustomWidget(
getName(), WGECamera::TWO_D, m_shutdownFlag.getCondition() );
bool success = m_widget.get();
if( success )
{
debugLog() << "Succesfully opened EEG View widget.";
m_widget->getScene()->addChild( m_node );
}
else
{
warnLog() << "Could not create EEG View widget.";
}
return success;
}
void WMEEGView::closeCustomWidget()
{
m_widget->getScene()->removeChild( m_node );
WKernel::getRunningKernel()->getGui()->closeCustomWidget( getName() );
}
osg::Node* WMEEGView::createText()
{
osg::Geode* geode = new osg::Geode();
......
......@@ -74,6 +74,7 @@ public:
/**
* Determine what to do if a property was changed.
*
* \param propertyName Name of the property.
*/
void slotPropertyChanged( std::string propertyName );
......@@ -111,6 +112,30 @@ private:
*/
osg::ref_ptr< osg::Node > m_node;
/**
* Bool flag to represent the state which is selected in the GUI.
* The module thread waits for changes of this flag and hiddes/displays its
* data according to it.
*/
WBoolFlag m_isActive;
/**
* The current active-state. Whether the widget is open and usable.
*/
bool m_wasActive;
/**
* Opens a custom widget and connects the m_node with it.
*
* \returns whether the custom widget could be opened successfully
*/
bool openCustomWidget();
/**
* Disconnects the m_node from the custom widget and closes the widget.
*/
void closeCustomWidget();
/**
* Sample HUD-Text. Copied from an OSG-Example
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment