Overview
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.
Expected Result
Symbol Facade Result
Example details
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;
{
symbolId = (*i)->elementId();
idsToRemove.insert(symbolId);
delete *i;
mySymbolFacades.erase( symbolId );
reportElementDestroyed( symbolId );
}
DtSelectionManager::instance( myAgentManager.de() ).removeFromCurrentSelection(idsToRemove);
myCurrentlySelectedSymbols.clear();
}
DtSymbolDriverToolbar.h
#pragma once
namespace makVrv
{
class DtDe;
class DtDriver;
}
namespace makVrv
{
namespace exampleSymbolFacade
{
{
public:
virtual ~DtSymbolDriverToolbar();
};
{
public:
virtual ~DtAddSymbolItem();
virtual void slot_driverStopped(DtDriver&);
virtual void slot_driverStarted(DtDriver&);
virtual void slot_listenForDriverManagerSignals();
virtual void on_triggered();
protected:
DtSignalConnectionManager myConnectionManager;
};
{
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();
};
}
}
DtSymbolDriverToolbar.cxx
#include <QtWidgets/QToolBar>
#include <QtWidgets/QAction>
#include <QtWidgets/QMenu>
#include <matrix/vlVector.h>
#include <time.h>
#include <math.h>
namespace makVrv
{
namespace exampleSymbolFacade
{
: 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" )
, myAction(0)
, myDe( de )
, myConnectionManager()
{
srand( time(NULL ) );
&DtAddSymbolItem::slot_listenForDriverManagerSignals, this));
}
DtAddSymbolItem::~DtAddSymbolItem()
{
}
void DtAddSymbolItem::slot_listenForDriverManagerSignals()
{
&DtAddSymbolItem::slot_listenForDriverManagerSignals, this));
myConnectionManager.manageConnection(myDe.driverManager().signal_driverStopped.connect(
boost::bind(&DtAddSymbolItem::slot_driverStopped,
this, _1)));
myConnectionManager.manageConnection(myDe.driverManager().signal_driverStarted.connect(
boost::bind(&DtAddSymbolItem::slot_driverStarted,
this, _1)));
}
void DtAddSymbolItem::slot_driverStarted(DtDriver& d)
{
if (d.className() == "DtExampleSymbolDriver")
{
myAction->setEnabled(true);
}
}
void DtAddSymbolItem::slot_driverStopped(DtDriver& d)
{
if (d.className() == "DtExampleSymbolDriver")
{
myAction->setEnabled(false);
}
}
{
if (myAction)
{
return myAction;
}
myAction->setText(DtMenuItem::tr("&Add new symbol..."));
myAction->setToolTip(DtMenuItem::tr("Create a new symbol..."));
myAction->setIcon(QIcon(QObject::tr("../data/Icons/UtilityAdd.svg")));
return myAction;
}
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 )
: DtMenuItem( "DtRotateSymbolItem" )
, myAction( 0 )
, myDe( de )
{
}
DtRotateSymbolItem::~DtRotateSymbolItem()
{
}
{
if (myAction)
{
return myAction;
}
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();
{
(*i)->setRotation( angle );
}
}
DtHideSymbolItem::DtHideSymbolItem( DtDe& de )
: DtMenuItem( "DtHideSymbolItem" )
, myAction( 0 )
, myDe( de )
{
}
DtHideSymbolItem::~DtHideSymbolItem()
{
}
{
if (myAction)
{
return myAction;
}
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();
{
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();
{
(*i)->setVisible( myAction->data().toBool() );
}
}
DtDeleteSymbolItem::DtDeleteSymbolItem( DtDe& de )
: DtMenuItem( "DtDeleteSymbolItem" )
, myAction( 0 )
, myDe( de )
{
}
DtDeleteSymbolItem::~DtDeleteSymbolItem()
{
}
{
if (myAction)
{
return myAction;
}
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;
}
}
}
DtRotateSymbolDialog.h
#pragma once
#include <QtWidgets/QDialog>
namespace makVrv
{
namespace exampleSymbolFacade
{
{ 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:
};
}
}
DtRotateSymbolDialog.cxx
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QLabel>
namespace makVrv
{
namespace exampleSymbolFacade
{
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->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();
}
}
}
DtSymbolFacade.h
#pragma once
#include <matrix/vlVector.h>
namespace makVrv
{
class DtSceneObjectAgent;
class DtWidgetLabelAgent;
class DtAgentManagerInterface;
class DtProjectedWidgetModelAgent;
}
namespace makVrv
{
namespace exampleSymbolFacade
{
{
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:
};
}
}
DtSymbolFacade.cxx
#include <vlutil/vlUtil.h>
#include <matrix/vlMath.h>
namespace makVrv
{
namespace exampleSymbolFacade
{
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( DtObserverMode::ModelSet2dIcons );
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
{
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;
}
}
}
DtExampleSymbolDriver.h
#pragma once
#include <boost/unordered_set.hpp>
#include <matrix/vlVector.h>
namespace makVrv
{
namespace exampleSymbolFacade
{
class DtSymbolFacade;
{
public:
typedef boost::unordered_set<DtSymbolFacade*> SymbolList;
public:
virtual ~DtExampleSymbolDriver();
virtual bool onStart();
virtual bool onStop();
virtual bool onTick();
virtual DtSymbolFacade* createSymbol(
const std::string& name,
const DtVector& pos );
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;
};
}
}
DtExampleSymbolDriver.cxx
#include <matrix/vlVector.h>
namespace makVrv
{
namespace exampleSymbolFacade
{
: makVrv::DtDriver( am, "DtExampleSymbolDriver" )
{
}
DtExampleSymbolDriver::~DtExampleSymbolDriver()
{
DtExampleSymbolDriver::onStop();
}
const std::string& DtExampleSymbolDriver::className()
const
{
}
bool DtExampleSymbolDriver::onStart()
{
DtScene& sceneDriver = myAgentManager.de().scene();
std::string maklandPath = myAgentManager.de().dePathConfiguration().userPath();
maklandPath += "/terrains/Makland.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();
{
reportElementDestroyed(i->first);
delete i->second;
}
mySymbolFacades.clear();
if (myChanges.hasChanges())
{
myAgentManager.de().dataBank().elementData().applyChanges(myChanges);
myChanges.clear();
}
return true;
}
bool DtExampleSymbolDriver::onTick()
{
return true;
}
DtSymbolFacade* DtExampleSymbolDriver::createSymbol(
{
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;
{
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 )
{
DtCoordinateConverter* coordConverter =
myAgentManager.de().sharedState().coordinateSystem().converter();
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();
{
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();
{
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() );
DtSelectionManager::IdSet::const_iterator selItr = curSel.begin();
DtSelectionManager::IdSet::const_iterator selEnd = curSel.end();
myCurrentlySelectedSymbols.clear();
for ( ; selItr != selEnd; ++selItr )
{
DtSymbolFacade* symbol = findSymbol(*selItr);
if ( symbol )
{
myCurrentlySelectedSymbols.insert( symbol );
}
}
}
void DtExampleSymbolDriver::slot_displayEngineAdded( const DtDeRecord& igRecord )
{
stop();
}
}
}
exampleSymbolFacade.cxx
using namespace makVrv;
using namespace makVrv::exampleSymbolFacade;
{
return true;
}
{
if ( igApp )
{
}
{
}
}
{
}
exampleSymbolFacade.h
#pragma once
#ifdef _WIN32
# ifdef exampleSymbolFacade_EXPORTS
# define DT_DLL_exampleSymbolFacade __declspec ( dllexport )
# else
# define DT_DLL_exampleSymbolFacade __declspec ( dllimport )
# endif
#else
# define DT_DLL_exampleSymbolFacade
#endif
#define DT_DE_PLUGIN_EXPORT_MACRO DT_DLL_exampleSymbolFacade
[<< Examples] [Home] [Top of Page]