3D PLM Enterprise Architecture

Data Access - File

The Object Navigator

Navigating through and customizing an object tree
Use Case

Abstract

This article accompanies the CAAOmbGeoNavigate use case. This use case explains how to create an object tree and navigate through it by expanding its nodes. It also explains how to customize the tree nodes by changing colors, by adding icons and by modifying short help. The way to refresh the object tree is also started on.


What You Will Learn With This Use Case

This use case is intended to illustrate the Object Navigator. Its main intent is to show how to create and navigate through an object tree. Basically, it shows how to:

Before getting to the use case itself, it is important to get an understanding of what the Object Navigator is. This is the goal of the next section. You can go directly to the use case itself if you are already familiar with all of these concepts.

[Top]

Some Important Concepts about the Object Navigator

A tree is a planar graph that contains no closed path. Because the components of a V5 document are organized as a tree, a tree is usually used to show the relationships between the components in a document window. This is called the document "object tree". Each component is a node of the tree, and each node can be expanded to display its sub-nodes, or collapsed to hide them. By clicking on a node, you display the children of the component represented by the node, and so on, thus discovering all of the components that make it up as well as the relationships between them. The set of services dedicated to the management of a tree is called the Object Navigator. By using the Object Navigator, you can display the relationships between any kind of objects provided that a parent-child link can be defined between these objects, such as the components in a V5 Product or Part document.

From a programmer standpoint, any object intended to be displayed within an object tree and managed by the object navigator must support the CATINavigateObject interface.

[Top]

The CAAOmbGeoNavigate Use Case

CAAOmbGeoNavigate is a use case of the CAAObjectModelerBase.edu framework that illustrates ObjectModelerBase framework capabilities.

[Top]

What Does CAAOmbGeoNavigate Do

This use case uses an existing pre-defined document type called "CAAGeometry" [1]. This document contains 

All these elements implements CATINavigateObject to be displayed in the object tree associated with the CAAGeometry document window. This window is a CATFrmGraphAnd3DWindow class which natively contains an object tree. 

The default representation for a node is:

By implementing CATINavigModify

Here is a picture to show node representations. 

The two next pictures show the short help for a point (left) and a line (right). 

You can see on the right picture that the default text of the short help is the same as the text of the node.

[Top]

How to Launch CAAOmbGeoNavigate

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. Next, you must launch a CATIA interactive session and go through the following scenario: 

[Top]

Where to Find the CAAOmbGeoNavigate Code

CAAOmbGeoNavigate code is located in the CAAOmbGeoNavigate.m use case module of the CAAObjectModelerBase.edu framework:

Windows InstallRootDirectory\CAAObjectModelerBase.edu\CAAOmbGeoNavigate.m
Unix InstallRootDirectory/CAAObjectModelerBase.edu/CAAOmbGeoNavigate.m

where InstallRootDirectory is the root directory of your CAA V5 installation. This module contains the implementations of the CATINavigateObject and CATINavigModify interfaces.

[Top]

Step-by-Step

There are five logical steps in CAAOmbGeoNavigate:

  1. Implementing CATINavigateObject on Root Object
  2. Implementing CATINavigateObject on Children Objects
  3. Implementing CATINavigModify to Modify Node Graphic Representation
  4. Implementing CATINavigModify to Modify the Default Short Help Text
  5. Using CATIRedrawEvent to Update the Object Tree 

We will now comment these sections by looking at the code.

[Top]

Implementing CATINavigateObject on Root Object

  1. Class definition

    The CAAOmbNavigateObjectRoot is the class which implements the CATINavigateObject interface. This interface being without adaptor, the CAAOmbNavigateObjectRoot class derives from CATBaseUnknown.

    #include "CATBaseUnknown.h"             // Needed to derive from
    class CATListValCATUnicodeString;       // Needed by GetIdentificators
    class CATListValCATBaseUnknown_var;     // Needed by GetChildren
    
    class CAAOmbNavigateObjectRoot : public CATBaseUnknown
    {
        CATDeclareClass;
    
      public :
        CAAOmbNavigateObjectRoot();
        virtual ~CAAOmbNavigateObjectRoot();
    	
        virtual CATListValCATUnicodeString       * GetIdentificators();
        virtual CATListValCATBaseUnknown_var     * GetChildren();
     
     ...
    };

    CATINavigateObject contains two basic methods that have to be coded:

  2.  Defines CAAOmbNavigateObjectRoot as an implementation of CATINavigateObject:
  3. The CAAOmbNavigateObjectRoot is the class which implements the CATINavigateObject for the CAASysGeomRootObj object. 

    #include "TIE_CATINavigateObject.h"
    TIE_CATINavigateObject(CAAOmbNavigateObjectRoot);
    
    
    CATImplementClass(CAAOmbNavigateObjectRoot,
    		DataExtension,
    		CATBaseUnknown,
    		CAASysGeomRootObj);
     
  4. CATINavigateObject::GetIdentificators.

    The GetIdentificators defines the text associated with the node. This text can be composed of several lines, each line being appended to the returned list. 

    CATListValCATUnicodeString * CAAOmbNavigateObjectRoot::GetIdentificators()
    {
      CATListOfCATUnicodeString *pIdent = new CATListOfCATUnicodeString;
    
      CATUnicodeString Name = "Root" ;
    
      CAAISysName * pISysName = NULL ;
      HRESULT rc = QueryInterface(IID_CAAISysName, (void**) & pISysName);
      if ( SUCCEEDED(rc) )
      {
         pISysName->GetName(Name);
         pISysName->Release();
         pISysName = NULL ;
      }
      pIdent -> Append(Name);
    
      return pIdent;
    
    }

    Each component of the CAAGeometry document implements the CAAISysName interface. This interface keeps the name of the instance. The name, retrieved thanks to the GetName method, is added to pIdent, the returned list. The text is only one line. 

  5. CATINavigateObject::GetChildren.

    This method returns a list of the children of the current node using several methods from specific CAA interfaces:

    CATListValCATBaseUnknown_var * CAAOmbNavigateObjectRoot::GetChildren()
    {
       CATListValCATBaseUnknown_var *pList = NULL ;
    
       CAAISysAccess *piSysAccess = NULL ;
       HRESULT rc = QueryInterface(IID_CAAISysAccess,
                                   (void**)&piSysAccess);
    
       if ( SUCCEEDED(rc) )
       {
          CATBaseUnknown *pContainer = NULL ;
          piSysAccess -> GetContainer(&pContainer);
          if ( NULL != pContainer) 
          {
             CAAISysCollection *piSysCollection = NULL ;
             rc = pContainer -> QueryInterface(IID_CAAISysCollection,
                                               (void**)&piSysCollection);
             if ( SUCCEEDED(rc) )
             {
                int count(0);
                piSysCollection -> GetNumberOfObjects(&count);
                if ( count > 1 )
                {
                   pList = new CATListValCATBaseUnknown_var();
    
                   for (int i=2; i<=count; i++)
                   {
                      CATBaseUnknown * pObject = NULL ;
                      piSysCollection -> GetObject(i, &pObject);
             ...
       }
       return pList;
    }

    GetChildren returns a list of pointers to the children of the root node, which are all of the objects of the model except the root. To do this, it gets a handle to the CAAISysAccess interface using the this pointer and uses this handle to get the container object which implements the CAAISysCollection interface from which we actually get all of the objects of the model which are appended to the list returned.

  6. Dictionary declaration as for any interface implementation, a dictionary entry is necessary in order to map the implementation name and shared library reference to the name of the interface:
    CAASysGeomRootObj   CATINavigateObject    libCAAOmbGeoNavigate

    You can find this entry in the CAAObjectModelerBase.edu.dico file.

[Top]

Implementing CATINavigateObject on Children Objects

  1. Class header
  2. The CAAOmbNavigateObjectChildren is the class which implements the CATINavigateObject interface. This interface being without adaptor, the CAAOmbNavigateObjectChildren class derives from CATBaseUnknown

  3. Define CAAOmbNavigateObjectChildren as an implementation of CATINavigateObject for several components

    The CAAOmbNavigateObjectRoot is the class which implements the CATINavigateObject for the CAASysPoint, CAASysLine, CAASysEllipse... objects. 

    CATBeginImplementClass(CAAOmbNavigateObjectChildren, DataExtension, CATBaseUnknown, 
                                              CAASysPoint);
    CATAddClassExtension(CAASysLine);
    CATAddClassExtension(CAASysEllipse);
    CATAddClassExtension(CAASysPlane);
    CATAddClassExtension(CAASysCircle);
    CATAddClassExtension(CAASysPolyline);
    CATAddClassExtension(CAASysCuboid);
    CATAddClassExtension(CAASysCylinder);
    CATEndImplementClass(CAAOmbNavigateObjectChildren); 
  4.  
  5. CATINavigateObject::GetIdentificators.

    The GetIdentificators method defines the text associated with the node. This text can be composed of several lines, each line being appended to the returned list. 

    CATListValCATUnicodeString * CAAOmbNavigateObjectChildren::GetIdentificators()
    {
      CATListOfCATUnicodeString *pIdent = new CATListOfCATUnicodeString;
    
      CATUnicodeString Name = "Children" ;
    
      CAAISysName * pISysName = NULL ;
      HRESULT rc = QueryInterface(IID_CAAISysName, (void**) & pISysName);
      if ( SUCCEEDED(rc) )
      {
         pISysName->GetName(Name);
         pISysName->Release();
         pISysName = NULL ;
      }
      pIdent -> Append(Name);
    
      return pIdent;
    
    }

    Each component of the CAAGeometry document implements the CAAISysName interface. This interface keeps the name of the instance. The name, retrieved thanks to the GetName method, is added to pIdent, the returned list. The text is only one line. 

  6. CATINavigateObject::GetChildren.

    This method returns an empty list since the root's children have no children.

    CATListValCATBaseUnknown_var * CAAOmbNavigateObjectChildren::GetChildren()
    {
       return NULL;
    }
  7. Dictionary declaration as for any interface implementation, a dictionary entry is necessary in order to map the implementation name and shared library reference to the name of the interface. There is a line for each component:
    CAASysLine   CATINavigateObject    libCAAOmbGeoNavigate
    CAASysPoint   CATINavigateObject    libCAAOmbGeoNavigate
    CAASysPlane   CATINavigateObject    libCAAOmbGeoNavigate
    CAASysCircle  CATINavigateObject    libCAAOmbGeoNavigate
    CAASysEllipse   CATINavigateObject    libCAAOmbGeoNavigate
    CAASysCuboid   CATINavigateObject    libCAAOmbGeoNavigate
    CAASysCylinder  CATINavigateObject    libCAAOmbGeoNavigate
    CAASysPolyline  CATINavigateObject    libCAAOmbGeoNavigate

    You can find this entry in the CAAObjectModelerBase.edu.dico file.

[Top]

Implementing CATINavigModify to Modify Node Graphic Representation

  1. Class header
  2. The CAAOmbNavigModifyRoot is the class which implements the CATINavigModify interface. This class derives from the CATNodeExtension class. 

    #include "CATNodeExtension.h"             // Needed to derive from
    class CATNavigInstance;
    
    class CAAOmbNavigModifyRoot : public CATNodeExtension
    {
      CATDeclareClass;
    
      public :
    
        CAAOmbNavigModifyRoot();
        virtual ~CAAOmbNavigModifyRoot();
    	
        void UpdateElem(CATNavigInstance * iInstance);
     
     ...
    };
    

    The CAAOmbNavigModifyRoot class re-implements only the UpdateElem method.

  3. Define CAAOmbNavigModifyRoot as an implementation of CATINavigModify 

    The CATINavigModify interface is not implemented on the object it-self, but on a late type based on the object's name. The last argument of the CATImplementClass macro must have the "_node" extension as part of its name. The first part being the object's name.

    // Creates the TIE Object
    #include "TIE_CATINavigModify.h"
    TIE_CATINavigModify(CAAOmbNavigModifyRoot);
    
    // Declares that the class is a data extension of CAASysGeomRootObj_node. 
    //
    CATImplementClass(CAAOmbNavigModifyRoot,
    	         DataExtension,
    		CATBaseUnknown,
    		CAASysGeomRootObj_node);

    CAASysGeomRootObj is the name of the root component. 

  4. CATINavigModify::UpdateElem

    The UpdateElem method enables you to modify the default visual aspect of a node. This implementation changes the background color of the node and attaches an icon to it. 

    void CAAOmbNavigModifyRoot::UpdateElem(CATNavigInstance * iInstance)
    {
       cout << "CAAOmbNavigModifyRoot::UpdateElem" << endl;
    
       CATIGraphNode *piGraphNode = NULL ;
       HRESULT rc = QueryInterface(IID_CATIGraphNode,
                                   (void**)&piGraphNode);
    
       if ( SUCCEEDED(rc) ) 
       {
          // Set the node to green instead of blue (default)
          piGraphNode -> SetColor(50);
    
          // Attach an icon to the node
          CATUnicodeString iconName("CAAOmbIcon2");
          piGraphNode -> SetPixelImage(iconName);
    
          piGraphNode -> Release();
          piGraphNode= NULL ;
       }
    }

    The CATIGraphNode interface being automatically implemented by a node, a simple QueryInterface on itself enables you to modify node characteristics. The SetColor takes as input an integer value representing the color of the node. SetPixelImage takes as input a character string representing the name of the icon. This name is searched for in the CNext/resources/graphic directory. It should be a bitmap file having a .bmp suffix.

    Note: iInstance, the input data is not used in this implementation but can be useful for your implementation. Refer to the section Implementing CATINavigModify to Modify the Default Short Help Text section for more details about its usage. 

  5. Dictionary definition

    Here is the dictionary entry necessary for the implementation of the CATINavigModify interface:

    CAASysGeomRootObj_node    CATINavigModify    libCAAOmbGeoNavigate

    You can find this entry in the CAAObjectModelerBase.edu.dico file.

[Top]

Implementing CATINavigModify to Modify the Default Short Help Text

  1. Class header
  2. The CAAOmbNavigModifyPoint is the class which implements the CATINavigModify interface. This class derives from the CATNodeExtension class.

    #include "CATNodeExtension.h"             // Needed to derive from
    class CATNavigInstance;
    
    class CAAOmbNavigModifyPoint : public CATNodeExtension
    {
      CATDeclareClass;
    
      public :
    
        CAAOmbNavigModifyPoint();
        virtual ~CAAOmbNavigModifyPoint();
    
        virtual HRESULT ModifyShortHelp(CATUnicodeString & ioText) ;
    ...
    };

    CAAOmbNavigModifyPoint re-implements only the ModifyShortHelp method.

  3. Define CAAOmbNavigModifyPoint as an implementation of the CATINavigModify interface

    Define CAAOmbNavigModifyPoint as an implementation of the CATINavigModify interface. Note that the last argument of the CATImplementClass macro must have the "_node" extension as part of its name.

    // Creates the TIE Object
    #include "TIE_CATINavigModify.h"
    TIE_CATINavigModify(CAAOmbNavigModifyPoint);
    
    
    CATImplementClass(CAAOmbNavigModifyRoot,
    	         DataExtension,
    		CATBaseUnknown,
    		CAASysPoint_node);

    CAASysPoint is the name of the point component.

  4. CATINavigModify::ModifyShortHelp

    The ModifyShortHelp method enables you to modify the default behavior for the short help of a node. In this example, the text contains the point coordinates.

    HRESULT  CAAOmbNavigModifyPoint::ModifyShortHelp(CATUnicodeString& ioText)
    {
        CATBaseUnknown_var Ref ;
    
        CATINavigElement *pINavigElement = NULL ;
        HRESULT rc = QueryInterface(IID_CATINavigElement, (void **) & pINavigElement);
        if ( SUCCEEDED(rc) )
        {
           // Do not release this pointer
           CATNavigInstance * pInst = pINavigElement->GetAssociatedInstance();
           if ( NULL != pInst)
           {
              Ref = pInst->GetReference();
           }else 
              rc = E_FAIL ;
    
           pINavigElement->Release();
           pINavigElement = NULL ;
        }
     ...
    

    The first part of the method consists in to retrieve a pointer on the point associated with the node. The CATINavigModify interface is implemented on the CAASysPoint_node late type. The GetAssociatedInstance method retrieves the CATNavigInstance class instance pointer which has kept a pointer to the CAASysPoint element. The GetReference method retrieves this CAASysPoint pointer.

    Then once, you have a pointer on the CAASysPoint, you can retrieve specific information.

        ...
        if (NULL_var != Ref)
        {
           CAAISysPoint *pISysPoint = NULL ;
           rc = Ref->QueryInterface(IID_CAAISysPoint, (void **) & pISysPoint);
           if ( SUCCEEDED(rc) )
           {
              float x,y,z ;
              pISysPoint->GetCoord(x,y,z);
           
              char PointPosistionBuffer[200];
              sprintf(PointPosistionBuffer,"X=%f Y=%f Z=%f",x,y,z);
    
              CATUnicodeString TextBuff (PointPosistionBuffer);
              ioText = TextBuff ;
    
              pISysPoint->Release();
              pISysPoint = NULL ;
           }
        }
        return S_OK ;
    }

    ioText is the inout parameter of the method. As input its value is the text of the node. The current implementation modifies the input text to create a new string from the three point coordinates. 

    The returned value is S_OK because even there is a problem to retrieve the point coordinates, a short help will be displayed with the default text. If the returned value is E_FAIL, no short help is displayed. 

  5. Dictionary definition

    Here is the dictionary entry necessary for the implementation of the CATINavigModify interface:

    CAASysPoint_node    CATINavigModify    libCAAOmbGeoNavigate

    You can find this entry in the CAAObjectModelerBase.edu.dico file.

[Top]

Using CATIRedrawEvent to Update the Object Tree 

The CATIRedrawEvent interface enables you to update the object tree. Here is an extract of the Point command [2]. 

      CATIRedrawEvent * piRedrawEvent = NULL;                
      rc =_pUIActiveObject->QueryInterface(IID_CATIRedrawEvent, (void**)&piRedrawEvent);
      if (SUCCEEDED(rc))
      {
        piRedrawEvent->Redraw();
        
        piRedrawEvent->Release();
        piRedrawEvent= NULL ;
      }

_pUIActiveObject is a pointer on the UI-active object of the CAAGeometry document [1]. This object is also the root object, in other words the CAASysGeomRootObj component. The QueryInterface is called on this component because it is the father node of the point element node. 

[Top]


In Short

This use case has demonstrated how to create and customize an object tree and navigate through it by expanding its nodes. It has also explained a number of concepts related to the Object Navigator.

[Top]


References

[1] The CAAGeometry Sample
[2] Associating a Dialog Box with a State
[Top]

History

Version: 1 [Mar 2000] Document created
Version: 2 [Aug 2003] Short Help introduction
[Top]

Copyright © 2000, Dassault Systèmes. All rights reserved.