3D PLM Enterprise Architecture |
User Interface - Commands |
Creating Contextual Menus in a State Dialog CommandCustomizing object's contextual menus in a state dialog command |
Use Case |
AbstractThis article shows how to create, in a state dialog command, a contextual menu displayed when right clicking on objects that implement a given interface. |
This use case is intended to show how to create a contextual menu that displays on objects that implement a given interface.
[Top]
The Logical command is a use case of the CAADialogEngine.edu framework that illustrates the DialogEngine framework capabilities.
[Top]
The Logical command is a state dialog command that creates a contextual menu, that is, a menu displayed when the end user right clicks on objects. This menu is displayed only if the object implements a given interface, namely CAAISysLine. A right click on such objects displays a contextual menu with three items, concatenated to the items provided by the window, since the document is displayed in a CATFrmGraphAnd3DWindow instance.
Window's items
Items added by the Logical command |
Clicking on one of these items displays the start, medium, or end point of the line. These points are temporary points ( CAAISysPoint objects) displayed by the ISO.
[Top]
See the section entitled "How to Launch the CAAGeometry Use Case" in the "The CAAGeometry Sample" use case for a detailed description of how this use case should be launched.
Then, in the window where you run the mkrun command, do not type the module name on the command line, but type CNEXT instead. When the application is ready, do the following:
[Top]
The Logical command is made of a single class named CAADegAnalysisLogCmd located in the CAADegGeoCommands.m module of the CAADialogEngine.edu framework:
Windows | InstallRootDirectory\CAADialogEngine.edu\CAADegGeoCommands.m\ |
Unix | InstallRootDirectory/CAADialogEngine.edu/CAADegGeoCommands.m/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
[Top]
To create the CAADegAnalysisLogCmd BuildGraph
method, there are
seven steps:
# | Step | Where |
---|---|---|
1 | Create the state dialog command header file | Header file |
2 | Enable the command to be instantiated by a command header | Source file |
3 | Implement the command state chart diagram | BuildGraph method |
4 | Create the Action Method | action method |
5 | Create the callback methods | action method |
6 | Manage the command lifecycle | callback method and destructor |
7 | Release the indication agent | Destructor or Cancel method |
[Top]
Below is the header file of the CAADegAnalysisLogCmd class that holds the code for this command.
#include "CATStateCommand.h" // Needed to derive from CATStateCommand class CATPathElementAgent; class CATISO; class CAAISysPoint; class CATMathPoint; class CAADegAnalysisLogCmd : public CATStateCommand { CmdDeclareResource(CAADegAnalysisLogCmd,CATStateCommand); public : CAADegAnalysisLogCmd(); virtual ~CAADegAnalysisLogCmd(); // Manages the focus CATStatusChangeRC Activate ( CATCommand * iCmd,CATNotification * iNotif); CATStatusChangeRC Cancel ( CATCommand * iCmd,CATNotification * iNotif); CATStatusChangeRC Desactivate( CATCommand * iCmd,CATNotification * iNotif); virtual void BuildGraph(); // Implements the statechart CATBoolean CreateCntxMenu(void * iUsefulData); void StartPoint (CATCommand * iCmd , CATNotification * iNotif, CATCommandClientData iData) ; void MediumPoint(CATCommand * iCmd , CATNotification * iNotif, CATCommandClientData iData) ; void EndPoint (CATCommand * iCmd , CATNotification * iNotif, CATCommandClientData iData) ; private : void ShowPoint(CATMathPoint &iPoint); CATPathElementAgent * _daPathElement ; CATISO * _ISO ; CAAISysPoint * _TemporaryPoint ; CATBaseUnknown * _Container; }; |
This class includes the following:
CmdDeclareResource
macro states that the resources for this command,
that is the prompts associated with the different states, are located in a
file named CAADegAnalysisLogCmd.CATNlsActivate
, Desactivate
, and Cancel
, are called by the
command selector to manage the command in the command stack BuildGraph
method creates the states, dialog agents, anf transitions
of the dialog command CreateCntxMenu
method is called when the end user clicks
a lineStartPoint
, MediumPoint
, and EndPoint
methods are the methods called
by the menu items ShowPoint
method creates and displays the required point.The data members are pointers to the path element agent used by the BuildGraph
method, the Interactive Set of Objects used to display the start,
medium, or end point as a temporary point that doesn't belong to the document,
and the document container that implements the point factory interface used to
create this point.
[Top]
The CAADegAnalysisLogCmd.cpp begins by:
... #include "CATCreateExternalObject.h" CATCreateClass(CAADegAnalysisLogCmd); ... |
This macro creates a C function that creates an instance of this class. This function is called by the command header to instantiate the command when the end user selects it if it weren't previously instantiated.
[Top]
Below is the code to write in the BuildGraph
method:
... void CAADegAnalysisLogCmd::BuildGraph() { _daPathElement = new CATPathElementAgent("SelFirstLine"); _daPathElement->AddElementType("CAAISysLine"); _daPathElement->SetBehavior( CATDlgEngWithContext | CATDlgEngRepeat | CATDlgEngWithUndo ); CATDialogState *stGetEltState = GetInitialState("stGetEltStateId"); stGetEltState->AddDialogAgent(_daPathElement); CATDialogTransition *pCntxMenuTransition = AddTransition ( stGetEltState, stGetEltState, IsLastModifiedAgentCondition(_daPathElement) , Action((ActionMethod) & CAADegAnalysisLogCmd::CreateCntxMenu) ) ; } ... |
A CATPathElement instance is created as a data member of the dialog command
class. It is valued for objects implementing the CAAISysLine interface
using the AddElementType
method, and when right clicking on their
representations thanks to the CATDlgEngWithContext
behavior in the SetBehavior
method. The CATDlgEngRepeat
behavior makes this dialog agent
repeatable. A single state is created, and the dialog agent is added to it. The
transition loops on this state, and whenever right clicking on a object matches
the dialog agent, the CreateCntxMenu
method is executed.
[Top]
This method is as follows.
... CATBooleanCAADegAnalysisLogCmd::CreateCntxMenu(void * iData) { // Selected Line CATPathElement * pLinePath = _daPathElement->GetValue(); CATBaseUnknown * pLine = NULL; if ( pLinePath && pLinePath->GetSize() ) { pLine = (*pLinePath)[pLinePath->GetSize()-1]; } if ( pLine) { // Retrieves the contextual menu CATNotification *pNotif = GetLastNotification(); CATDlgContextualMenu *pCntxMenu = ((CATContext*)pNotif)->GetContextualMenu(); // Default Item Title CATString StartString ("StartPoint"); CATString MediumString("MediumPoint"); CATString EndString ("EndPoint") ; // all these dialog objects are deleted when the contextual menu // is deleted. The command does't delete them. CATDlgSeparatorItem *Separator = new CATDlgSeparatorItem(pCntxMenu,"separator"); CATDlgPushItem * StartPoint = new CATDlgPushItem(pCntxMenu,StartString) ; CATDlgPushItem * MediumPoint = new CATDlgPushItem(pCntxMenu,MediumString) ; CATDlgPushItem * EndPoint = new CATDlgPushItem(pCntxMenu,EndString) ; // NLS data in the NLS file of this command ( see this header file ) StartPoint->SetTitle(CATMsgCatalog::BuildMessage( "CAADegAnalysisLogCmd", "StartPointTitle")); MediumPoint->SetTitle(CATMsgCatalog::BuildMessage( "CAADegAnalysisLogCmd", "MediumPointTitle")); EndPoint->SetTitle(CATMsgCatalog::BuildMessage( "CAADegAnalysisLogCmd", "EndPointTitle")); // Callbacks AddAnalyseNotificationCB(EndPoint, EndPoint->GetMenuIActivateNotification(), (CATCommandMethod) & CAADegAnalysisLogCmd::EndPoint, (void*) pLine ); AddAnalyseNotificationCB(MediumPoint, MediumPoint->GetMenuIActivateNotification(), (CATCommandMethod) & CAADegAnalysisLogCmd::MediumPoint, (void*) pLine ); AddAnalyseNotificationCB(StartPoint, StartPoint->GetMenuIActivateNotification(), (CATCommandMethod) & CAADegAnalysisLogCmd::StartPoint, (void*) pLine ); } return TRUE ; } ... |
This method is called when the transition of the BuildGraph
method is executed. It:
AddAnalyseNotificationCB
method
to the called methods.Since the contextual menu is retrieved and updated with push items and a separator rather than being created, there is no need to delete the push items and the separator. They will be deleted when the contextual menu itself will be deleted by the destructor of the class that creates it. In the same way, there is no need to remove the callbacks. They will also be automatically removed when the contextual menu will be deleted.
[Top]
The callback methods retrieve each the appropriate point to display, and call
the ShowPoint
method. Only StartPoint is shown here
... void CAADegAnalysisLogCmd::StartPoint(CATCommand * iSendingCommand, CATNotification * iSentNotification, CATCommandClientData iUsefulData) { CATBaseUnknown * pLine = (CATBaseUnknown *) iUsefulData; if ( pLine ) { CAAISysLine * Line = NULL; HRESULT rc = pLine->QueryInterface(IID_CAAISysLine, (void**)&Line); if (SUCCEEDED(rc)) { CATMathPoint point ; Line->GetStartPoint(point) ; ShowPoint(point); Line -> Release(); } } } ... |
The ShowPoint
method creates a point instance, if it doesn't
already exist, that implements the CAAISysPoint interface, and the point
factory returns a pointer to this interface, and adds it to the Interactive Set
of Objects. This makes it possible to display it. Then ShowPoint
assigns to that instance the coordinates of the CATMathPoint instance passed
from the called back method and updates the ISO with this point..
... void CAADegAnalysisLogCmd::ShowPoint(CATMathPoint & iPoint) { if ( NULL == _piTemporaryPoint ) { CAAISysGeomFactory * piSysGeomFactory = NULL; HRESULT rc = _pContainer->QueryInterface(IID_CAAISysGeomFactory, (void**)&piSysGeomFactory); if (SUCCEEDED(rc)) { piSysGeomFactory -> Create(CAAISysGeomFactory::Point, IID_CAAISysPoint, (CATBaseUnknown**)&_piTemporaryPoint); _pISO->AddElement(_piTemporaryPoint); piSysGeomFactory -> Release(); piSysGeomFactory=NULL; } } if ( NULL != _piTemporaryPoint ) { _piTemporaryPoint->SetCoord((float) iPoint.GetX(), (float) iPoint.GetY(), (float) iPoint.GetZ()); _pISO->UpdateElement(_piTemporaryPoint) ; } } ... |
[Top]
The following methods are called by the command selector to manage the command when it becomes the active one, or when another command becomes active instead.
... CATStatusChangeRC CAADegAnalysisLogCmd::Cancel(CATCommand *iCmd, CATNotification *iNotif) { if (_TemporaryPoint) { _ISO->RemoveElement(_TemporaryPoint); _TemporaryPoint->Release(); _TemporaryPoint= NULL ; } return (CATStatusChangeRCCompleted); } ... |
[Top]
A pointer to the selection agent was created in the command BuildGraph
method as a data member to be accessed and used in different methods. It
should be released when it becomes useless. This can be done in the command
destructor, as shown here. This could also be done in the Cancel
method called just before the destructor.
CAADegAnalysisLogCmd::CAADegAnalysisLogCmd() { ... if ( NULL != _daPathElement ) { _daPathElement ->RequestDelayedDestruction() ; _daPathElement = NULL ; } ... |
[Top]
The same command should now react to any object whose representation is right
clicked. This includes the viewer background. To do this, replace the AddElementType
method by the AcceptOnNotify
method to make the dialog agent match
any right click, and remove the CATDlgEngWithContext
behavior from
the AddElementType
method. The rest of the method is unchanged.
void CAADegAnalysisLogCmd::BuildGraph() { _daPathElement = new CATPathElementAgent("SelFirstLine"); _daPathElement->AcceptOnNotify(NULL, "CATContext"); _daPathElement->SetBehavior(CATDlgEngRepeat); CATDialogState * stGetEltState = GetInitialState("stGetEltStateId"); stGetEltState->AddDialogAgent(_daPathElement); CATDialogTransition * pCntxMenuTransition = AddTransition (stGetEltState, // From state stGetEltState, // To state IsLastModifiedAgentCondition(_daPathElement), Action((ActionMethod) & CAADegAnalysisLogCmd::CreateCntxMenu)); } |
The CreateCtxMenu
method is the same as above.
[Top]
Contextual menus can be set onto objects implementing a given interface by any dialog command.
[Top]
[Top] |
Version: 1 [Jan 2000] | Document created |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.