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 deleting symbols using an item on the symbol's context menu.
A menu item for deleting the selected symbols was first created and registered with the menu assembler. The menu item should only be enabled if a symbol is selected, so the menu item's on_aboutToShow method performs this check.
void DtDeleteSymbolItem::on_aboutToShow()
{
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
myAction->setEnabled( ! symbolDriver->selectedSymbols().empty() );
}
When the user clicks on the menu item, it tells the driver to delete the selected symbols.
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
symbolDriver->deleteSelectedSymbols();
The driver's deleteSelectedSymbols method was created to iterate over all selected objects and delete the symbols.
void DtExampleSymbolDriver::deleteSelectedSymbols()
{
SymbolList::iterator i = myCurrentlySelectedSymbols.begin();
SymbolList::iterator e = myCurrentlySelectedSymbols.end();
DtSelectionManager::IdSet idsToRemove;
for ( ; i != e; ++i )
{
symbolId = (*i)->elementId();
idsToRemove.insert(symbolId);
delete *i;
mySymbolFacades.erase( symbolId );
reportElementDestroyed( symbolId );
}
DtSelectionManager::instance( myAgentManager.de() ).removeFromCurrentSelection(idsToRemove);
myCurrentlySelectedSymbols.clear();
}
DtSymbolDriverToolbar5.h
#pragma once
namespace makVrv
{
class DtDe;
}
namespace makVrv
{
namespace exampleSymbolFacade5
{
{
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:
virtual ~DtDeleteSymbolItem();
virtual void on_aboutToShow();
virtual void on_triggered();
protected:
};
{
public:
DtSymbolFacadeExampleMenu(DtDe& de);
virtual ~DtSymbolFacadeExampleMenu();
};
}
}
DtSymbolDriverToolbar5.cxx
#include <QtGui/QToolBar>
#include <QtGui/QAction>
#include <QtGui/QMenu>
#include <matrix/vlVector.h>
#include <time.h>
#include <math.h>
namespace makVrv
{
namespace exampleSymbolFacade5
{
: 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 )
, 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;
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 )
, 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 )
, 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() );
}
}
DtDeleteSymbolItem::DtDeleteSymbolItem( DtDe& de )
, myAction( 0 )
, myDe( de )
{
}
DtDeleteSymbolItem::~DtDeleteSymbolItem()
{
}
{
myAction->setText( DtMenuItem::tr("&Delete symbol...") );
myAction->setToolTip( DtMenuItem::tr("Delete symbol...") );
myAction->setIcon( QIcon(QObject::tr("../data/Icons/UtilityClose.svg")) );
return myAction;
}
void DtDeleteSymbolItem::on_aboutToShow()
{
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
myAction->setEnabled( ! symbolDriver->selectedSymbols().empty() );
}
void DtDeleteSymbolItem::on_triggered()
{
DtExampleSymbolDriver* symbolDriver = (DtExampleSymbolDriver*)
myDe.driverManager().findDriver( "DtExampleSymbolDriver" );
symbolDriver->deleteSelectedSymbols();
}
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;
}
}
}
DtRotateSymbolDialog5.h
#pragma once
#include <QtGui/QDialog>
class QDoubleSpinBox;
namespace makVrv
{
namespace exampleSymbolFacade5
{
{ 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;
};
}
}
DtRotateSymbolDialog5.cxx
#include <QtGui/QDoubleSpinBox>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>
#include <QtGui/QLabel>
namespace makVrv
{
namespace exampleSymbolFacade5
{
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 );
okButton->setText( "OK" );
okButton->setDefault( true );
okCancelLayout->addWidget( okButton );
connect( okButton, SIGNAL(clicked()), this, SLOT(accept()) );
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();
}
}
}
DtSymbolFacade5.h
#pragma once
#include <boost/signal.hpp>
namespace makVrv
{
class DtSceneObjectAgent;
class DtWidgetLabelAgent;
class DtAgentManagerInterface;
class DtProjectedWidgetModelAgent;
}
namespace makVrv
{
namespace exampleSymbolFacade5
{
{
public:
virtual ~DtSymbolFacade();
virtual makVrv::DtWidgetLabelAgent& widgetLabelAgent();
virtual void setVisible( bool visible );
virtual bool visible() const;
virtual void setPosition(
const DtVector& pos );
virtual void setRotation( float angleInDegrees );
protected:
void initialize();
protected:
makVrv::DtSceneObjectAgent* mySceneObjectAgent;
makVrv::DtProjectedWidgetModelAgent* myProjectedWidgetModelAgent;
makVrv::DtWidgetLabelAgent* myWidgetLabelAgent;
};
}
}
DtSymbolFacade5.cxx
#include <vrvCore/DtProjectedWidgetModelAgent.hpp>
#include <vrvCore/DtWidgetLabelAgent.hpp>
#include <vrvCore/DtSceneObjectAgent.hpp>
#include <vlutil/vlUtil.h>
#include <matrix/vlMath.h>
namespace makVrv
{
namespace exampleSymbolFacade5
{
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;
}
}
}
DtExampleSymbolDriver5.h
#pragma once
#include <boost/unordered_set.hpp>
namespace makVrv
{
namespace exampleSymbolFacade5
{
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,
virtual SymbolList selectedSymbols() const;
virtual void deleteSelectedSymbols();
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;
};
}
}
DtExampleSymbolDriver5.cxx
#include <vrvCore/DtWidgetAgent.hpp>
#include <vrvCore/DtWidgetLabelAgent.hpp>
#include <vrvCore/DtSceneObjectAgent.hpp>
#include <vrvCore/DtProjectedWidgetModelAgent.hpp>
#include <matrix/vlVector.h>
namespace makVrv
{
namespace exampleSymbolFacade5
{
: 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::deleteSelectedSymbols()
{
SymbolList::iterator i = myCurrentlySelectedSymbols.begin();
SymbolList::iterator e = myCurrentlySelectedSymbols.end();
DtSelectionManager::IdSet idsToRemove;
for ( ; i != e; ++i )
{
symbolId = (*i)->elementId();
idsToRemove.insert(symbolId);
delete *i;
mySymbolFacades.erase( symbolId );
reportElementDestroyed( symbolId );
}
DtSelectionManager::instance( myAgentManager.de() ).removeFromCurrentSelection(idsToRemove);
myCurrentlySelectedSymbols.clear();
}
void DtExampleSymbolDriver::positionSymbol(
DtSymbolFacade* symbol,
const DtVector& pos )
{
myAgentManager.de().sharedState().coordinateSystem().converter();
coordConverter->setupTopoFrame( pos );
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();
}
}
}
exampleSymbolFacade5.cxx
using namespace makVrv;
using namespace makVrv::exampleSymbolFacade5;
{
return true;
}
{
if ( igApp )
{
}
{
}
}
{
}
exampleSymbolFacade5.h
#pragma once
#ifdef _WIN32
# ifdef EXAMPLESYMBOLFACADE5_EXPORTS
# define DT_DLL_EXAMPLESYMBOLFACADE5 __declspec ( dllexport )
# else
# define DT_DLL_EXAMPLESYMBOLFACADE5 __declspec ( dllimport )
# endif
#else
# define DT_DLL_EXAMPLESYMBOLFACADE5
#endif
#define DT_DE_PLUGIN_EXPORT_MACRO DT_DLL_EXAMPLESYMBOLFACADE5