3D PLM Enterprise Architecture |
User Interface - Command |
Creating a Command that Consists in a Dialog WindowCreating a command without states |
Use Case |
AbstractThis article shows how to create a command without states using a single dialog box. |
This use case is intended to show how to use a dialog box as a standalone command without states. This command is an undefined command which is unknown by the command selector [1]. It means that it can run in parallel with the active command known by the command selector.
[Top]
CAAAfrBoundingElementCmd is a use case of the CAAApplicationFrame.edu framework that illustrates the ApplicationFrame framework capabilities.
[Top]
CAAAfrBoundingElementCmd is a dialog command made up of a dialog box. It creates a bounding element, namely a sphere, for all or some of the geometric objects currently existing in the document. While computing the bounding sphere, it displays a progress bar.
The dialog is as follows:
The document displayed includes points, lines, planes and circles. Select the CAAAfrBoundingElementCmd command.
The Model Bounding Sphere dialog box is displayed. You can check the options that take the points and lines into account in the bounding sphere computing, and press Compute. This launches the bounding sphere computation. A progress bar is shown in the dialog box to show the progress status.
The bounding sphere is computed. The dialog box was moved to show the bounding sphere displayed using three of its great circles. You can create other elements or delete some elements and next click "Compute" : a new bounding sphere will be displayed. The command remains active as long as you don't click Close.
The CAAAfrBoundingElementCmd use case explains how to create such command but does not explain
[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. For the specific scenario :
Do not type the module name on the command line, but type CNEXT instead. When the application is ready, do the following:
[Top]
The CAAAfrBoundingElementCmd use case is made of a single class named CAAAfrBoundingElementCmd located in the CAAAfrGeoCommands.m module of the CAAApplicationFrame.edu framework:
Windows | InstallRootDirectory\CAAApplicationFrame.edu\CAAAfrGeoCommands.m\ |
Unix | InstallRootDirectory/CAAApplicationFrame.edu/CAAAfrGeoCommands.m/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
CAAAfrBoundingElementCmd is part of the "CAA V5: Geometry Analysis" workbench.
[Top]
To create the CAAAfrBoundingElementCmd command, there are four steps:
[Top]
The CAAAfrBoundingElementCmd class header file is as follows.
... class CAAAfrBoundingElementCmd : public CATDlgDialog { DeclareResource(CAAAfrBoundingElementCmd, CATDlgDialog); public : CAAAfrBoundingElementCmd(); virtual ~CAAAfrBoundingElementCmd(); private : ... void ClickClose(CATCommand * iSendingCommand, CATNotification * iSentNotification, CATCommandClientData iUsefulData); void EditorClose (CATCallbackEvent iEvent, void *iFrom, CATNotification *iNotification, CATSubscriberData iData, CATCallback iCallBack ); private : ... CATFrmEditor * _pEditor ; }; |
This header file contains the following declaration:
DeclareResource
macro states that the resources of the CAAAfrBoundingElementCmd
command class are located in the CAAAfrBoundingElementCmd.CATNls file.
If resources were assigned to the CATDlgDialog class, they
would be concatenated with those of CAAAfrBoundingElementCmdEditorClose
, when the current document is closedNow, there is the description of the source file.
[Top]
The CAAAfrBoundingElementCmd command is launched from a CATCommandHeader class instance [5]. In the CAA V5: Geometry Analysis" workbench, you have such line:
... new CAAAfrGeoAnalysisWkbHeader("CAAAfrBoundingEltHdr" , "CAAAfrGeoCommands", "CAAAfrBoundingElementCmd" , (void *) NULL); ... |
So, to be able to create an instance of the command by its name you should have these two lines in its source file:
... #include "CATCreateExternalObject.h" CATCreateClass(CAAAfrBoundingElementCmd); ... |
[Top]
The CAAAfrBoundingElementCmd command is not seen by the command selector. Its
starting mode is undefined: it is the default mode of a CATDlgDialog class. For
such commands, and contrary to the common usage with dialog boxes that use a Build
method to instantiate the dialog objects contained in the dialog box, the
constructor should perform this instantiation because the command header calls
only this constructor. So the contents of the constructor is as a Build
method [6] :
... CAAAfrBoundingElementCmd::CAAAfrBoundingElementCmd() :CATDlgDialog ((CATApplicationFrame::GetFrame())->GetMainWindow(), "CAAAfrBoundingElementId", CATDlgGridLayout | CATDlgWndBtnClose ) { // 1- Creating the dialog objects // 2- Arranging the dialog objects // 3- Declaring the callbacks associated with the dialog objects // 4- Declaring the callback for a document's closure ... _pEditor = CATFrmEditor::GetCurrentEditor(); } ... |
The dialog window has the application main window as parent [7].
The CATDlgGridLayout
style enables you to use the grid
layout for its internal arrangement [8] and the CATDlgWndBtnClose
style is one of the fourth style recommended.
_pEditor
is a data member which keeps the current editor when
the command is launched. This data will be useful to check if the document that
the end user want close is the document associated with this command- See the Managing the Lifecycle of the Command and of its Objects
section.
The GetCurrentEditor method must not be used outside the CATCommand class constructor .
... CATDlgFrame * pPointLineGlobalFrame = new CATDlgFrame(this, "PointLineGlobalFrameId",CATDlgGridLayout|CATDlgFraNoFrame); CATDlgFrame * pPointLineCheckFrame = new CATDlgFrame(pPointLineGlobalFrame, "PointLineCheckFrameId",CATDlgGridLayout|CATDlgFraNoFrame); CATDlgFrame * pPointLineHeaderFrame = new CATDlgFrame (pPointLineGlobalFrame, "PointLineHeaderFrameId",CATDlgGridLayout|CATDlgFraNoFrame); CATDlgLabel * pPointLineLabel = new CATDlgLabel(pPointLineHeaderFrame, "LabelPointLineId"); ... See the code for the details ... |
... pPointLineLabel->SetGridConstraints(0,0,1,1,CATGRID_LEFT); pPointLineSep ->SetGridConstraints(0,1,1,1,CATGRID_4SIDES|CATGRID_CST_HEIGHT); ... See the code for the details // Show the window SetVisibility(CATDlgShow); ... |
... AddAnalyseNotificationCB(this, this->GetWindCloseNotification(), (CATCommandMethod)&CAAAfrBoundingElementCmd::ClickClose, NULL); AddAnalyseNotificationCB(this, this->GetDiaCLOSENotification(), (CATCommandMethod)&CAAAfrBoundingElementCmd::ClickClose, NULL); ... |
The ClickClose
method is executed
whenever the dialog window is closed:
by the Close button (GetDiaCLOSENotification
) or the banner (GetWindCloseNotification
).
This step is mandatory. If the end user closes the current document and the command is alive: it will not be automatically deleted once it is not seen by the command selector. So your command must set a callback when the document will send the "close" event.
... if ( (NULL != _pEditor) && (NULL != CATFrmLayout::GetCurrentLayout()) ) { ::AddCallback(this, CATFrmLayout::GetCurrentLayout(), CATFrmEditor::EDITOR_CLOSE_ENDED(), (CATSubscriberMethod)&CAAAfrBoundingElementCmd::EditorClose, NULL); } ... |
Refer to the technical article [7] to understand
the role of the unique CATFrmLayout class instance. It is the object
which sends the CATFrmEditor::EDITOR_CLOSE_ENDED
notification.
[Top]
The command can be deleted for two reasons:
When the end user closes itself the window:
void CAAAfrBoundingElementCmd::ClickClose(CATCommand * iSendingCommand, CATNotification * iSentNotification, CATCommandClientData iUsefulData) { SetVisibility(CATDlgHide); ... RequestDelayedDestruction(); } |
In this case, the ClickClose
method is called.
It hides the dialog box and requests the dialog box to be deleted.
When the document is closed:
void CAAAfrBoundingElementCmd::EditorClose(CATCallbackEvent iEvent, void * iFrom, CATNotification * iNotification, CATSubscriberData iClientData, CATCallback iCallBack ) { if ( _pEditor == iFrom ) { RequestDelayedDestruction(); } } |
The unique CATFrmLayout class instance sends a "EDITOR_CLOSE_ENDED"
notification when anything document is closed. So the EditorClose
method is called. It is necessary to check
that it is the "good" editor before closing the window. iFrom
is the editor associated with the document which is closing. If iFrom
is the good document the dialog box deletion is requested.
The destructor, as usual, releases the data members and set NULL the data member pointers. In addition, the current destructor must delete the callback on the CATFrmLayout:
CAAAfrBoundingElementCmd::~CAAAfrBoundingElementCmd() { // releases the data members and set NULL the data member pointers ... if ( (NULL != _pEditor) && ( NULL != CATFrmLayout::GetCurrentLayout()) ) { ::RemoveSubscriberCallbacks(this,CATFrmLayout::GetCurrentLayout()); } _pEditor = NULL ; } |
If
the command uses interactive objects such as the ISO, HSO, PSO objects [9],
in the destructor you must not remove any objects from this interactive objects.
The CATFrmEditor which manages them has already made it. But if the
window is closed by the end user, you must remove the objects in the ClickClose
method.
[Top]
This use case shows how to create a command without state that consists only in a dialog window and that in addition, is not known by the command selector.
[Top]
Version: 1 [Jan 2000] | Document created |
Version: 2 [Fev 2003] | Document updated |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.