This example builds on the symbol facade and driver from the previous examples in this tutorial series, and shows additional steps that are necessary for hiding symbols using an item on the symbol's context menu.
A menu item was created and registered with the menu assembler. Since the menu item will need to know whether the selected symbols are currently visible or hidden, on_aboutToShow not only checks to make sure a symbol is selected, but also checks whether any of the selected symbols are hidden and stores this information for use when the user clicks on the item.
void DtHideSymbolItem::on_aboutToShow()
{
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
if ( symbolDriver->selectedSymbols().empty() )
{
myAction->setEnabled( false );
return;
}
myAction->setEnabled( true );
DtExampleSymbolDriver::SymbolList::iterator i, e;
DtExampleSymbolDriver::SymbolList curSelSymbols =
symbolDriver->selectedSymbols();
bool hiddenSelected = false;
i = curSelSymbols.begin();
e = curSelSymbols.end();
for ( ; i != e; ++i )
{
if ( ! (*i)->visible() )
{
hiddenSelected = true;
}
}
if ( hiddenSelected )
{
myAction->setText( DtMenuItem::tr("&Show symbol...") );
myAction->setToolTip( DtMenuItem::tr("Show symbol...") );
myAction->setIcon( QIcon(QObject::tr("../data/Icons/ObserverView.svg")) );
myAction->setData( qVariantFromValue(hiddenSelected) );
}
else
{
myAction->setText( DtMenuItem::tr("&Hide symbol...") );
myAction->setToolTip( DtMenuItem::tr("Hide symbol...") );
myAction->setIcon( QIcon(QObject::tr("../data/Icons/ObserverViewsDelete.svg")) );
myAction->setData( qVariantFromValue(hiddenSelected) );
}
}
When the user clicks on the menu item, it retrieves the value stored during the on_aboutToShow check, and updates the visibility of all selected symbols using the list from the driver.
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
DtExampleSymbolDriver::SymbolList selectedSymbols =
symbolDriver->selectedSymbols();
DtExampleSymbolDriver::SymbolList::iterator i = selectedSymbols.begin();
DtExampleSymbolDriver::SymbolList::iterator e = selectedSymbols.end();
float angle = rotateDialog.selectedRotationAmount();
for ( ; i != e; ++i )
{
(*i)->setRotation( angle );
}
The DtSymbolFacade was also updated to include methods for setting and querying the symbol's visibility.
void DtSymbolFacade::setVisible( bool visible )
{
mySceneObjectAgent->setVisible( visible );
}
bool DtSymbolFacade::visible() const
{
DtSceneObject* obj =
mySceneObjectAgent->findObject();
if ( obj )
{
return obj->isVisible();
}
return false;
}
DtSymbolDriverToolbar4.h
#pragma once
namespace makVrv
{
class DtDe;
}
namespace makVrv
{
namespace exampleSymbolFacade4
{
{
public:
virtual ~DtSymbolDriverToolbar();
};
{
public:
virtual ~DtAddSymbolItem();
virtual void on_triggered();
protected:
};
{
public:
virtual ~DtRotateSymbolItem();
virtual void on_aboutToShow();
virtual void on_triggered();
protected:
};
{
public:
virtual ~DtHideSymbolItem();
virtual void on_aboutToShow();
virtual void on_triggered();
protected:
};
{
public:
DtSymbolFacadeExampleMenu(DtDe& de);
virtual ~DtSymbolFacadeExampleMenu();
};
}
}
DtSymbolDriverToolbar4.cxx
#include <QtGui/QToolBar>
#include <QtGui/QAction>
#include <QtGui/QMenu>
#include <matrix/vlVector.h>
#include <time.h>
#include <math.h>
namespace makVrv
{
namespace exampleSymbolFacade4
{
: DtToolbar( de, "DtSymbolDriverToolbar" )
{
}
DtSymbolDriverToolbar::~DtSymbolDriverToolbar()
{
}
{
bar->setWindowTitle( QObject::tr("Symbol Driver Toolbar") );
bar->setObjectName( QObject::tr("Symbol Driver Toolbar") );
return bar;
}
DtAddSymbolItem::DtAddSymbolItem( DtDe& de )
: DtMenuItem( "DtAddSymbolItem" )
, myDe( de )
{
srand( time(NULL ) );
}
DtAddSymbolItem::~DtAddSymbolItem()
{
}
{
act->setText( DtMenuItem::tr("&Add new symbol...") );
act->setToolTip( DtMenuItem::tr("Create a new symbol...") );
act->setIcon( QIcon(QObject::tr("../data/Icons/UtilityAdd.svg")) );
return act;
}
void DtAddSymbolItem::on_triggered()
{
static int numSymbolsCreated = 0;
DtString symbolName( "Symbol #" );
symbolName += DtString(numSymbolsCreated);
double rand_x = 4000.0*((double)rand())/RAND_MAX;
double rand_y = 4000.0*((double)rand())/RAND_MAX;
double rand_z = 4000.0*((double)rand())/RAND_MAX;
DtVector location( rand_x, rand_y, rand_z );
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
symbolDriver->createSymbol( symbolName.string(), location );
++numSymbolsCreated;
}
DtRotateSymbolItem::DtRotateSymbolItem( DtDe& de )
: DtMenuItem( "DtRotateSymbolItem" )
, myAction( 0 )
, myDe( de )
{
}
DtRotateSymbolItem::~DtRotateSymbolItem()
{
}
{
myAction->setText( DtMenuItem::tr("&Rotate symbol...") );
myAction->setToolTip( DtMenuItem::tr("Rotate symbol...") );
myAction->setIcon( QIcon(QObject::tr("../data/Icons/SetRestore.svg")) );
return myAction;
}
void DtRotateSymbolItem::on_aboutToShow()
{
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
myAction->setEnabled( ! symbolDriver->selectedSymbols().empty() );
}
void DtRotateSymbolItem::on_triggered()
{
DtRotateSymbolDialog rotateDialog( myDe );
int retCode = rotateDialog.exec();
if ( retCode == QDialog::Rejected )
{
return;
}
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
DtExampleSymbolDriver::SymbolList selectedSymbols =
symbolDriver->selectedSymbols();
DtExampleSymbolDriver::SymbolList::iterator i = selectedSymbols.begin();
DtExampleSymbolDriver::SymbolList::iterator e = selectedSymbols.end();
float angle = rotateDialog.selectedRotationAmount();
for ( ; i != e; ++i )
{
(*i)->setRotation( angle );
}
}
DtHideSymbolItem::DtHideSymbolItem( DtDe& de )
: DtMenuItem( "DtHideSymbolItem" )
, myAction( 0 )
, myDe( de )
{
}
DtHideSymbolItem::~DtHideSymbolItem()
{
}
{
myAction->setText( DtMenuItem::tr("&Hide symbol...") );
myAction->setToolTip( DtMenuItem::tr("Hide symbol...") );
myAction->setIcon( QIcon(QObject::tr("../data/Icons/ObserverViewsDelete.svg")) );
return myAction;
}
void DtHideSymbolItem::on_aboutToShow()
{
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
if ( symbolDriver->selectedSymbols().empty() )
{
myAction->setEnabled( false );
return;
}
myAction->setEnabled( true );
DtExampleSymbolDriver::SymbolList::iterator i, e;
DtExampleSymbolDriver::SymbolList curSelSymbols =
symbolDriver->selectedSymbols();
bool hiddenSelected = false;
i = curSelSymbols.begin();
e = curSelSymbols.end();
for ( ; i != e; ++i )
{
if ( ! (*i)->visible() )
{
hiddenSelected = true;
}
}
if ( hiddenSelected )
{
myAction->setText( DtMenuItem::tr("&Show symbol...") );
myAction->setToolTip( DtMenuItem::tr("Show symbol...") );
myAction->setIcon( QIcon(QObject::tr("../data/Icons/ObserverView.svg")) );
myAction->setData( qVariantFromValue(hiddenSelected) );
}
else
{
myAction->setText( DtMenuItem::tr("&Hide symbol...") );
myAction->setToolTip( DtMenuItem::tr("Hide symbol...") );
myAction->setIcon( QIcon(QObject::tr("../data/Icons/ObserverViewsDelete.svg")) );
myAction->setData( qVariantFromValue(hiddenSelected) );
}
}
void DtHideSymbolItem::on_triggered()
{
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
DtExampleSymbolDriver::SymbolList selectedSymbols =
symbolDriver->selectedSymbols();
DtExampleSymbolDriver::SymbolList::iterator i = selectedSymbols.begin();
DtExampleSymbolDriver::SymbolList::iterator e = selectedSymbols.end();
for ( ; i != e; ++i )
{
(*i)->setVisible( myAction->data().toBool() );
}
}
DtSymbolFacadeExampleMenu::DtSymbolFacadeExampleMenu(DtDe& de)
: DtMenu(de, "DtSymbolFacadeExampleMenu")
{
}
DtSymbolFacadeExampleMenu::~DtSymbolFacadeExampleMenu()
{
}
QMenu* DtSymbolFacadeExampleMenu::createMenu( DtDe& de,
QWidget* parent )
{
QMenu* menu =
new QMenu(QObject::tr(
"Example"), parent);
return menu;
}
}
}
DtRotateSymbolDialog4.h
#pragma once
#include <QtGui/QDialog>
class QDoubleSpinBox;
namespace makVrv
{
namespace exampleSymbolFacade4
{
{ Q_OBJECT;
public:
Qt::WindowFlags f = 0 );
virtual ~DtRotateSymbolDialog();
float selectedRotationAmount() const;
private:
DtRotateSymbolDialog( const DtRotateSymbolDialog& orig );
DtRotateSymbolDialog& operator = ( const DtRotateSymbolDialog& orig );
protected:
void setupGui();
protected:
QDoubleSpinBox* myRotationSpinner;
};
}
}
DtRotateSymbolDialog4.cxx
#include <QtGui/QDoubleSpinBox>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>
#include <QtGui/QLabel>
namespace makVrv
{
namespace exampleSymbolFacade4
{
QWidget* parent , Qt::WindowFlags f )
, myRotationSpinner( 0 )
{
setupGui();
setWindowTitle(tr("Rotate Symbol"));
}
DtRotateSymbolDialog::~DtRotateSymbolDialog()
{
}
void DtRotateSymbolDialog::setupGui()
{
QVBoxLayout* dialogLayout = new QVBoxLayout();
QHBoxLayout* fieldLayout = new QHBoxLayout();
{
fieldLabel->setText( "Rotation (deg):" );
fieldLayout->addWidget( fieldLabel );
myRotationSpinner = new QDoubleSpinBox();
myRotationSpinner->setMinimum( 0 );
myRotationSpinner->setDecimals( 1 );
myRotationSpinner->setMaximum( 360 );
fieldLayout->addWidget( myRotationSpinner );
}
dialogLayout->addLayout( fieldLayout );
QHBoxLayout* okCancelLayout = new QHBoxLayout();
{
okCancelLayout->addStretch( 1 );
QPushButton* okButton = new QPushButton();
okButton->setText( "OK" );
okButton->setDefault( true );
okCancelLayout->addWidget( okButton );
connect( okButton, SIGNAL(clicked()), this, SLOT(accept()) );
QPushButton* cancelButton = new QPushButton();
cancelButton->setText( "Cancel" );
cancelButton->setDefault( false );
okCancelLayout->addWidget( cancelButton );
connect( cancelButton, SIGNAL(clicked()), this, SLOT(reject()) );
okCancelLayout->addStretch( 1 );
}
dialogLayout->addLayout( okCancelLayout );
setLayout( dialogLayout );
}
float DtRotateSymbolDialog::selectedRotationAmount() const
{
return myRotationSpinner->value();
}
}
}
DtSymbolFacade4.h
#pragma once
#include <boost/signal.hpp>
class DtVector;
namespace makVrv
{
class DtSceneObjectAgent;
class DtWidgetLabelAgent;
class DtAgentManagerInterface;
class DtProjectedWidgetModelAgent;
}
namespace makVrv
{
namespace exampleSymbolFacade4
{
{
public:
virtual ~DtSymbolFacade();
virtual void setVisible( bool visible );
virtual bool visible() const;
virtual void setPosition( const DtVector& pos );
virtual void setRotation( float angleInDegrees );
protected:
void initialize();
protected:
};
}
}
DtSymbolFacade4.cxx
#include <vlutil/vlUtil.h>
#include <matrix/vlMath.h>
namespace makVrv
{
namespace exampleSymbolFacade4
{
DtAgentManagerInterface& sceneInterface,
DtElementID id )
: myElementId( id )
, mySceneObjectAgent( DtSceneObjectAgent::create(sceneInterface) )
, myProjectedWidgetModelAgent( DtProjectedWidgetModelAgent::create(sceneInterface) )
, myWidgetLabelAgent( DtWidgetLabelAgent::create(sceneInterface) )
{
initialize();
}
DtSymbolFacade::~DtSymbolFacade()
{
myProjectedWidgetModelAgent->removeWidget( myWidgetLabelAgent );
DtDELETE( myWidgetLabelAgent );
mySceneObjectAgent->removeModel( myProjectedWidgetModelAgent );
DtDELETE( myProjectedWidgetModelAgent );
DtDELETE( mySceneObjectAgent );
}
void DtSymbolFacade::initialize()
{
if ( ! mySceneObjectAgent ) DtTHROW_NEW( DtCorruptedState, "Unable to create scene object agent." );
if ( ! myProjectedWidgetModelAgent ) DtTHROW_NEW( DtCorruptedState, "Unable to create projected widget model agent." );
if ( ! myWidgetLabelAgent ) DtTHROW_NEW( DtCorruptedState, "Unable to create widget label agent." );
mySceneObjectAgent->setModelSet( 5 );
mySceneObjectAgent->setElementID( myElementId );
mySceneObjectAgent->addModel( myProjectedWidgetModelAgent, DtStateVisualizer::EntityVisualizerType );
myWidgetLabelAgent->setOverlay( DtOverlayManager::ModelSet_2D_Icons_Overlay );
myWidgetLabelAgent->setBackgroundImage( "$(DATA_DIR)/images/ArrowCircle.png" );
myWidgetLabelAgent->setColor( 0.8f, 0.8f, 0.8f, 1.0f );
myWidgetLabelAgent->setSize( 32, 32 );
myProjectedWidgetModelAgent->addWidget( myWidgetLabelAgent );
myWidgetLabelAgent->setEventsEnabled( true );
}
void DtSymbolFacade::setVisible( bool visible )
{
mySceneObjectAgent->setVisible( visible );
}
bool DtSymbolFacade::visible() const
{
DtSceneObject* obj =
mySceneObjectAgent->findObject();
if ( obj )
{
return obj->isVisible();
}
return false;
}
{
return myElementId;
}
DtWidgetLabelAgent& DtSymbolFacade::widgetLabelAgent()
{
return *myWidgetLabelAgent;
}
void DtSymbolFacade::setPosition( const DtVector& pos )
{
mySceneObjectAgent->setPosition( 0, pos );
}
void DtSymbolFacade::setRotation( float angleInDegrees )
{
myWidgetLabelAgent->setRotation( DtDeg2Rad(angleInDegrees) );
}
DtElementEntry::ElementType DtSymbolFacade::elementType()
{
return DtElementEntry::Entity;
}
}
}
DtExampleSymbolDriver4.h
#pragma once
#include <boost/unordered_set.hpp>
class DtVector;
namespace makVrv
{
namespace exampleSymbolFacade4
{
class DtSymbolFacade;
{
public:
typedef boost::unordered_set<DtSymbolFacade*> SymbolList;
public:
virtual ~DtExampleSymbolDriver();
virtual const std::string& className() const;
virtual bool onStart();
virtual bool onStop();
virtual bool onTick();
virtual DtSymbolFacade* createSymbol( const std::string& name,
const DtVector& pos );
virtual SymbolList selectedSymbols() const;
protected:
virtual void positionSymbol( DtSymbolFacade* symbol, const DtVector& pos );
virtual void slot_currentSelectionChanged(
protected:
typedef boost::unordered_map<makVrv::DtElementID,DtSymbolFacade*> SymbolFacadeMap;
SymbolFacadeMap mySymbolFacades;
SymbolList myCurrentlySelectedSymbols;
};
}
}
DtExampleSymbolDriver4.cxx
#include <matrix/vlVector.h>
namespace makVrv
{
namespace exampleSymbolFacade4
{
: makVrv::DtDriver( am, "DtExampleSymbolDriver" )
{
}
DtExampleSymbolDriver::~DtExampleSymbolDriver()
{
DtExampleSymbolDriver::onStop();
}
const std::string& DtExampleSymbolDriver::className() const
{
static std::string name = "DtExampleSymbolDriver";
return name;
}
bool DtExampleSymbolDriver::onStart()
{
DtScene& sceneDriver = myAgentManager.de().scene();
std::string maklandPath = myAgentManager.de().dePathConfiguration().userPath();
maklandPath += "/terrains/MaklandNoSpeedtrees.mtf";
sceneDriver.loadTerrain( maklandPath );
DtSelectionManager& selectionManager =
DtSelectionManager::instance( myAgentManager.de() );
selectionManager.signal_currentSelectionChanged.connect( boost::bind(
&DtExampleSymbolDriver::slot_currentSelectionChanged,
this, _1, _2, _3, _4 ) );
return true;
}
bool DtExampleSymbolDriver::onStop()
{
DtSelectionManager& selectionManager =
DtSelectionManager::instance( myAgentManager.de() );
selectionManager.signal_currentSelectionChanged.disconnect(
boost::bind( &DtExampleSymbolDriver::slot_currentSelectionChanged,
this, _1, _2, _3, _4 ) );
SymbolFacadeMap::iterator i = mySymbolFacades.begin();
SymbolFacadeMap::iterator e = mySymbolFacades.end();
for ( ; i != e; ++i )
{
delete i->second;
}
mySymbolFacades.clear();
return true;
}
bool DtExampleSymbolDriver::onTick()
{
return true;
}
DtSymbolFacade* DtExampleSymbolDriver::createSymbol(
const std::string& name, const DtVector& pos )
{
DtElementID elementId = myAgentManager.createNewUniqueId();
DtSymbolFacade* symbol = new DtSymbolFacade( myAgentManager, elementId );
symbol->widgetLabelAgent().setColor( 0.8f, 0.8f, 0.8f, 1.0f );
symbol->widgetLabelAgent().setSize( 32, 32 );
mySymbolFacades.insert( std::make_pair(elementId,symbol) );
reportElementCreated( elementId, 0, DtSymbolFacade::elementType() );
positionSymbol( symbol, pos );
return symbol;
}
DtSymbolFacade* DtExampleSymbolDriver::findSymbol(
DtElementID symbolId )
{
SymbolFacadeMap::iterator itr = mySymbolFacades.find( symbolId );
if ( itr != mySymbolFacades.end() )
return itr->second;
return NULL;
}
DtExampleSymbolDriver::SymbolList
DtExampleSymbolDriver::selectedSymbols() const
{
return myCurrentlySelectedSymbols;
}
void DtExampleSymbolDriver::positionSymbol(
DtSymbolFacade* symbol, const DtVector& pos )
{
DtCoordinateConverter* coordConverter =
myAgentManager.de().sharedState().coordinateSystem().converter();
coordConverter->setupTopoFrame( pos );
DtVector position;
coordConverter->enuToCig_coordTrans( pos, position );
symbol->setPosition( position );
}
void DtExampleSymbolDriver::slot_currentSelectionChanged(
const DtSelectionManager::IdSet& selected,
const DtSelectionManager::IdSet& deselected,
DtSelectionManager::SelectionType newType,
DtSelectionManager::SelectionType oldType )
{
DtSelectionManager::IdSet::const_iterator i, e;
e = selected.end();
i = selected.begin();
for ( ; i != e; ++i )
{
SymbolFacadeMap::iterator itr = mySymbolFacades.find( *i );
if ( itr != mySymbolFacades.end() )
{
DtWidgetLabelAgent& label = itr->second->widgetLabelAgent();
label.setColor( 1.0f, 1.0f, 1.0f, 1.0f );
label.setSize( 36, 36 );
}
}
e = deselected.end();
i = deselected.begin();
for ( ; i != e; ++i )
{
SymbolFacadeMap::iterator itr = mySymbolFacades.find( *i );
if ( itr != mySymbolFacades.end() )
{
DtWidgetLabelAgent& label = itr->second->widgetLabelAgent();
label.setColor( 0.8f, 0.8f, 0.8f, 1.0f );
label.setSize( 32, 32 );
}
}
DtSelectionManager& selMgr =
DtSelectionManager::instance( myAgentManager.de() );
const DtSelectionManager::IdSet& curSel = selMgr.currentSelections();
DtSelectionManager::IdSet::const_iterator selItr = curSel.begin();
DtSelectionManager::IdSet::const_iterator selEnd = curSel.end();
myCurrentlySelectedSymbols.clear();
DtSymbolFacade* symbol;
for ( ; selItr != selEnd; ++selItr )
{
if ( symbol = findSymbol(*selItr) )
{
myCurrentlySelectedSymbols.insert( symbol );
}
}
}
void DtExampleSymbolDriver::slot_displayEngineAdded( const DtDeRecord& igRecord )
{
stop();
start();
}
}
}
exampleSymbolFacade4.cxx
using namespace makVrv;
using namespace makVrv::exampleSymbolFacade4;
{
return true;
}
{
if ( igApp )
{
}
{
}
}
{
}
exampleSymbolFacade4.h
#pragma once
#ifdef _WIN32
# ifdef EXAMPLESYMBOLFACADE4_EXPORTS
# define DT_DLL_EXAMPLESYMBOLFACADE4 __declspec ( dllexport )
# else
# define DT_DLL_EXAMPLESYMBOLFACADE4 __declspec ( dllimport )
# endif
#else
# define DT_DLL_EXAMPLESYMBOLFACADE4
#endif
#define DT_DE_PLUGIN_EXPORT_MACRO DT_DLL_EXAMPLESYMBOLFACADE4