VkComponent(3x)

VkComponent - Abstract base class for all ViewKit components

As shipped in IRIX 6.5.15. Last changed in IRIX 6.5.5.

NAME
     VkComponent - Abstract base class for all ViewKit components

INHERITS FROM
     VkCallbackObject

HEADER FILE
     #include <Vk/VkComponent.h>

PUBLIC PROTOCOL SUMMARY
   Displaying Components
              virtual void show()
              virtual void hide()
              void manage()
              void unmanage()


   Destructor
              virtual ~VkComponent()


   Access Functions
              char * name() const
              virtual const char *className();
              Widget baseWidget() const
              virtual operator Widget();


   Access Functions - ViewKit 2.1 only
              VkScreen *getScreen();


   Supported Callbacks
              static const char * const deleteCallback


   Utility Functions
              virtual Boolean okToQuit()
              virtual void    afterRealizeHook()
              static  Boolean isComponent(VkComponent *comp)


   Dynamic Loading Support
              static VkComponent *loadObject(const char *name,
                                    Widget parent,
                                    const char *className,
                                    const char *filename);

CLASS DESCRIPTION
     The VkComponent class is the basis of nearly all classes in the ViewKit.
     This abstract class defines the basic protocol followed by all components
     in the ViewKit, as well as those created by application developers.  The
     concept of a user interface component is the fundamental underlying idea
     on which the ViewKit is based. A component is simply a C++ class that has
     some semantics and a presentation. Nearly all classes in the ViewKit are
     components, including VkApp, VkSimpleWindow, and so on. The ViewKit
     provides many component classes, and encourages an approach to building
     applications based on building application-specific components.
     Developers generally write applications by writing and connecting new
     components.

SUBCLASS PROTOCOL SUMMARY
   Handling Widget Destruction
              void installDestroyHandler();
              void removeDestroyHandler();
              virtual void widgetDestroyed();


   Resource Support
              void setDefaultResources ( const Widget w ,
                                         const String *resourceSpec );
              void getResources ( const XtResourceList resources,
                                  const int numResources);


   Data Members
         char   *_name;
         Widget  _baseWidget;
         Widget& _w;

   Constructors
              VkComponent( const char *name );
              VkComponent();



   Deriving Subclasses
     The VkComponent class is an abstract class whose primary purpose is to
     support subclasses. The following are a set of guidelines for writing
     components based on the VkComponent class.

          All classes derived from VkComponent (known as components) support
          one or more widgets.  Widgets encapsulated by a component should
          form a subtree below a single root widget.

          The root of the widget subtree created by a component is referred to
          as the base widget of the object. The base widget must be created by
          the derived class, and assigned to the _baseWidget member inherited
          from the VkComponent class.

          Components should usually create the base widget and all other
          widgets in the class constructor. The constructor should manage all
          widgets except the base widget, which should be left unmanaged. The
          entire subtree represented by a component can be managed or
          unmanaged using the member functions supported by VkComponent.

          All constructors should take at least two arguments, a widget to be
          used as the parent of the component's base widget, and a string to
          be used as the name of the base widget. The name argument should be
          passed on to the VkComponent constructor, which makes a copy of the
          string. All references to a component's name should use the _name
          member inherited from VkComponent, or the name() access function.

          All component classes should override the virtual className() member
          function, which is expected to return a string that identifies the
          name of the class.  Components should define any Xt callbacks
          required by the class as static member functions.  These functions
          are normally declared in the private section of the class, because
          they are seldom useful to derived classes.

          All Xt callback functions installed for Motif widgets should be
          passed the this pointer as client data.  Callback functions are
          expected to retrieve this pointer, cast it to the expected object
          type and call a corresponding member function. By convention, static
          member functions used as callbacks have the same name as the member
          function they call, with the word Callback appended. For example,
          the static member function startCallback() calls the member function
          start().  Member functions called by static member functions are
          often private, but may also be part of the public or subclass
          protocol of the class. Occasionally it is useful to declare one of
          these functions to be virtual, allowing derived classes to change
          the function ultimately called as a result of a callback.

          Derived classes should call installDestroyHandler() immediately
          after creating a component's base widget. This sets up callbacks
          that handle certain unpleasant problems that can occur with regard
          to widget destruction.

          Derived classes that need to specify default resources to function
          correctly should call the function setDefaultResources() with an
          appropriate resource list before creating the component's base
          widget.

          Derived classes that wish to initialize data members from values in
          the resource database should define an appropriate resource
          specification and call the function getResources() immediately after
          the installDestroyHandler() function.

FUNCTION DESCRIPTIONS
   VkComponent

              VkComponent( const char *name );
              VkComponent();


          The VkComponent constructor initializes the baseWidget to NULL and
          initializes the _name member of the object. If a string is given as
          an argument to the constructor, this name is copied. Otherwise, the
          component is given the temporary name "component". In any case, a
          dynamically allocated string is assigned to the _name member. The
          VkComponent constructor is declared to be protected and can only be
          called from derived classes.

   installDestroyHandler
              void installDestroyHandler();


          This function should be called by derived class immediately after
          the component's base widget is created. It registers an
          XmNdestroyCallback function for the base widget that helps ensure
          that the widget is not deleted out from under the object. When
          linking with the debugging version of the ViewKit library, a warning
          will be issued about any class that does not install a
          destroyHandler.

   removeDestroyHandler
              void removeDestroyHandler();


          This function removes the destroy callback installed by
          installDestroyHandler(). Occasionally, it may be necessary to
          disable the destroy callback. The VkComponent class removes the
          callback in the destructor before destroying the widget, to prevent
          referencing an object after it has been deleted.

   widgetDestroyed
              virtual void widgetDestroyed();


          This virtual function is called when a component's base widget is
          destroyed. The default VkComponent member function simply NULL's the
          _baseWidget member. Derived classes may override this function is
          additional tasks need to be performed in the event of widget
          destruction.  However, they should always call their base class's
          method as well.

   setDefaultResources
              void setDefaultResources ( const Widget w,
                                         const String *resourceSpec );

          This member function can be called to store a collection of
          resources in the application's resource database. This is usually
          done to associate a set of resources with all instances of a class
          automatically. Resources are loaded with the lowest precedence, so
          that these resources are true defaults. They can be overridden
          easily in any resource file.

          The setDefaultResources() function should be called in the
          constructor, before creating the base widget, and with the parent
          argument to the component as the first argument. The second argument
          must be a NULL-terminated array of strings, written in the style of
          an X resource database specification. All resources should be
          written as if they applied to all widgets below the base widget.
          When resources are loaded, the value of _name is prepended to all
          entries, unless that entry begins with the "-" or '+' character. A
          leading '-' arranges for the resources to be specified relative to
          the base widget, and reduces the chances of name space collisions. A
          leading "+" adds the class name of the application to the resource
          specification. This is useful for overriding resources set by SGI
          Schemes, which are automatically qualified by the application's
          class name, without requiring the component to be tied to a specific
          application in advance.

          For example, the following code segment specifies a default label
          string of the "pushButton" widget. The resources also specify that
          the resource string "*sampleExists: TRUE" should be added to the
          resource database without qualifying the resource any further (i.e.
          do not prepend _name). This is useful in rare situations where it is
          desirable to add global resources to the database.


           String  SampleComponent::_defaultResources[] = {
                  "*pushbutton.labelString:  Push Me",
                  "-*sampleExists:  TRUE",
                  NULL
           };
           SampleComponent::SampleComponent(const char *name,
                                           Widget parent) :
                  VkComponent(name)
           {
              // Load any class-defaulted resources
              // for this object

              setDefaultResources(parent, _defaultResources  );

              // Create an unmanaged widget as the top of
              // the widget hierarchy

              _baseWidget =  XtVaCreateWidget ( _name,
                                                xmRowColumnWidgetClass,
                                                parent,
                                                NULL ) ;
              // install a callback to guard against
              // unexpected widget destruction

              installDestroyHandler();

              _pushButton = XmCreatePushButton( _baseWidget,
                                                "pushbutton",
                                                 NULL, 0)

              // ...



   getResources
              void getResources ( const XtResourceList resources,
                                  const int numResources );


          This member function can be used in conjunction with an XtResource
          list to initialize members of a specific class from values retrieved
          from the resource database. It must be called after the base widget
          has been created.

          For example, the following code segments demonstrate the
          initialization of a data member, _verbose, from the resource data
          base. Default values are specified in the XtResource structure, but
          the ultimate value is determined by the value of the resource named
          "verbose" in the resource database.


           // Header file

           class SampleComponent : public VkComponent
           {
              private:

               static XtResource _resources[];

              protected:

               Boolean _verbose;

            public:

              SampleComponent(const char *, Widget);
           };

           // Source file

           #include "SampleComponent.h"

           XtResource SampleComponent::_resources [] = {
           {
               "verbose",
               "Verbose",
               XmRBoolean,
               sizeof ( Boolean ),
               XtOffset ( SampleComponent *, _verbose ),
               XmRString,
               (XtPointer) "FALSE",
             },
           };



           SampleComponent::SampleComponent(Widget parent,
                                            const char *name) :
                    VkComponent (name)
           {
              // Create an unmanaged widget as the
              // top of the widget hierarchy

              _baseWidget =  XtVaCreateWidget ( _name,
                                                xmFrameWidgetClass,
                                                parent,
                                                NULL ) ;

              // install a callback to guard against
              // unexpected widget destruction

              installDestroyHandler();

              // Initialize members from resource database

              getResources ( _resources, XtNumber(_resources) );

              // ...
           }



   _name
              char   *_name;


          All components are expected to have a unique name, which is
          maintained by VkComponent as the _name data member. This member must
          be used as the name of the base widget for the resource support to
          work correctly.

   _baseWidget
              Widget  _baseWidget;
              Widget& _w;

          Many functions and other components rely on the existence of a "base
          widget" for all components. The base widget is the widget at the top
          of the widget tree for the component. This widget should be assigned
          to _baseWidget when it is created. The data member _w is a reference
          to the _baseWidget member and exists only for historical reasons.

   show()
              virtual void show();


          This member function should be called to display the widgets in a
          component. The show() member function must be called initially to
          display the widgets, and may be called after hide() has been called
          to redisplay the component. In the simplest case, show() is
          analogous to calling XtManageChild() on the base Widget of the
          component. Note that XtManageChild() should never be called
          explicitly on the base widget. Conceptually, show() does whatever is
          required to display a component, which may involve more than simply
          managing widgets. Show() is a higher level of abstraction for the
          total set of operations required to make a user interface component
          visible.

   hide
              virtual void hide();


          This member function causes a component to disappear from the
          screen.  Like show(), hide() is analogous to
          XtUnmanageChild(_baseWidget). However, it is a higher level
          abstraction that individual classes may implement differently in
          order to perform whatever actions are necessary to remove a
          component from the visible screen.

   manage()
   unmanage()
              void manage() ;
              void unmanage();


          Manage() and unmanage() simply call show() and hide(), respectively.
          These functions exist for compatibility with earlier versions of
          this class.

   name()
            const char * name() const


          Returns the instance name of a component object.

   className

           virtual const char *className();


          Returns the name of the class to which the component belongs. Each
          subclass of VkComponent is expected to override this function. The
          class name is used by various ViewKit facilities. The class name for
          the VkComponent class is "VkComponent".

   baseWidget
           Widget baseWidget() const { return _baseWidget; }


          This access function returns the base widget of a component.
          Normally, components are as encapsulated as possible, and
          programmers should avoid operating directly on a component's base
          widget outside the class. However, certain operations may require
          access to a component's base widget. For example, after
          instantiating a component as a child of an XmForm widget, it may be
          necessary to set various constraint resources.

   getScreen() - ViewKit 2.1 only
           VkScreen *getScreen();


          Returns the VkScreen object associated with this component.

   operator Widget
           virtual operator Widget();


          The operator Widget allows a VkComponent object to be passed
          directly to functions that expect a widget. By default, the operator
          converts the component into its base widget. Some derived classes
          may override this operator to return a different widget. Note that
          the object itself and not a pointer to the object must be used.

          For example, assume that SampleComponent is a class derived from
          VkComponent. We could do something like this:


            Widget form = XmCreateForm(parent,
                                       "form",
                                        NULL, 0);
            SampleComponent *sc = new SampleComponent(form,
                                                      "sample");
            XtVaSetValues(*sc,
                           XmNtopAttachment, XmATTACH_FORM,
                           NULL);

          The Widget operator is used in this example as a result of the
          implicit cast done to the *sc variable since XtVaSetValues() expects
          a parameter of type Widget as its first argument.

   deleteCallback
            static const char * const deleteCallback;


          This string identifies the name of a ViewKit member function
          callback supported by all classes derived from VkComponent.

   okToQuit
            virtual Boolean okToQuit();


          This function can be used to support "safe quit" mechanisms. In
          general, this method is only used by VkSimpleWindow and subclasses
          (See VkApp(3X)and VkSimpleWindow(3X)). When VkApp::quitYourself() is
          called, VkApp checks all registered windows before quitting, If any
          window's method returns FALSE, the application does not exit. Some
          windows may wish to check components contained within that window.
          OkToQuit() provides a standard way to perform this check. By default
          okToQuit() returns TRUE. If any component, including a
          VkSimpleWindow wishes to check with other objects, it arrange to
          call the okToQuit() functions of contained components and implement
          the desired logic. The ViewKit only calls this method for
          VkSimpleWindow (and derived classes).

   afterRealizeHook
            virtual void afterRealizeHook();


          Some components need to know when widgets in the component have been
          realized (i.e. a window exists for the widget), or when the widgets
          have been set to their final size. This virtual function is called
          in response to the first MapNotify event received for the base
          widget of a component.  At this point, all windows have been created
          and the widgets have just become visible.

   isComponent
            static Boolean isComponent(VkComponent *comp);


          This function applies certain heuristics to determine whether a
          given pointer represents a valid VkComponent object. If a pointer
          points to a VkComponent that has not been deleted, this function
          will always return TRUE. Otherwise the function returns FALSE. It is
          possible, although highly unlikely, that this function could
          mistakenly identify a dangling pointer to a deleted object as a
          valid object. This could happen if another component were to be
          allocated at exactly the same address as the deleted object a
          pointer previously pointed to.
DYNAMIC LOADING
     ViewKit supports the ability to dynamically load a class from a dynamic
     shared object or library. To participate in this scheme, a VkComponent
     subclass must provide a few hooks, using specific conventions. Classes
     created with RapidApp(TM) are automatically set up for dynamic loading.
     To prepare a class by hand, you must provide a creation function, and an
     optional Interface Map. (See VkCallbackObject).

          A creation function is a static member function that creates an
          instance of the associated class. The creation function must be
          named Create<ClassName>, where <ClassName> is the name of the class,
          and must take two arguments, the name of the instance and a parent
          widget.  The class is expected to instantiate an object and return
          it as a VkComponent*. For example, a class LabeledText would have a
          declaration in its header:


          static VkComponent *CreateLabeledText(const char *name, Widget parent);



          and then in the source file:


          VkComponent *LabeledText::CreateLabeledText(const char *name, Widget parent)
          {
             LabeledText *obj = new LabeledText(name, parent);

             return obj;
          }



   loadObject
              static VkComponent *loadObject(const char *name,
                                 Widget parent,
                                 const char *className,
                                 const char *filename);



          If a component has the creation member function described above, it
          can be loaded by calling VkComponent::loadObject, with an instance
          name, parent widget, name of the class to be instantiated, and the
          name of a file in which the object is located. For example, a class
          LabeledText, which is found in a shared library named liblbtext.so,
          can be loaded as:


           LabeledText *lb = VkComponent::loadObject("labeledtext",
                                      parent,
                                         "LabeledText",
                                 "liblbtext.so");




EXAMPLES
     The following example component implements a very simple color selector
     that allows users to select from three colors, red, green, or blue. The
     component supports toggle buttons for each of these colors.  All toggle
     buttons are in a radio box widget, so that only one can be selected at a
     time. The class installs callbacks for each toggle button, which
     eventually call the virtual function colorChanged().

     Applications can choose to use this class in one of two ways.

          First, the member function colorChanged() is declared to be virtual,
          so applications could incorporate this component by creating a
          subclass. This choice is attractive when the application needs to
          perform additional work when a toggle is selected, or when the
          component needs to be expanded or modified in some way.

          Second, applications might choose to use the colorChangedCallback()
          supported by the ColorChoice class to call a member function of
          another object when a color is selected.  This option is most
          appropriate when the class already has the desired functionality and
          when trying to avoid the additional work required to write a
          subclass.


           //////////////////////////////////////////////////////////////
           //
           // Header file for ColorChoice
           //////////////////////////////////////////////////////////////
           #ifndef _COLORCHOICE_H
           #define _COLORCHOICE_H
           #include <Vk/VkComponent.h>

           class ColorChoice : public VkComponent
           {

            private:

              // Array that describes interactions with
              // Xt resource manager

              static String  _defaultColorChoiceResources[];

              // Callbacks to interface with Motif

              static void newColorCallback (Widget,
                                            XtPointer,
                                            XtPointer);
            protected:

              // Widgets created by this class

              Widget  _blue;
              Widget  _green;
              Widget  _radioBox;
              Widget  _red;

              virtual void newColor ( Widget, XtPointer );

            public:

              ColorChoice(const char *, Widget);
              ~ColorChoice();
              const char* className();

              static const char * const colorChangedCallback;
              enum Color { RED, GREEN, BLUE };
           };
           #endif

           /////////////////////////////////////////////////////////////
           //
           // Source file for ColorChoice
           /////////////////////////////////////////////////////////////
           #include "ColorChoice.h
           #include <Xm/Frame.h>
           #include <Xm/RowColumn.h>
           #include <Xm/ToggleB.h>

           // These are default resources for widgets in objects
           // of this class All resources will be prepended by
           // *<name> at instantiation, where <name> is the name
           // of the specific instance, as well as the name of
           // the baseWidget. These are only defaults, and may be
           // overridden in a resource file by providing a more
           // specific resource name

           String ColorChoice::_defaultColorChoiceResources[]={
                  "*red.labelString:  Red",
                  "*green.labelString:  Green",
                  "*blue.labelString:  Blue",
                  NULL
           };

           const char * const ColorChoice::colorChangedCallback = "colorChanged";

           ColorChoice::ColorChoice(const char *name,
                                    Widget parent) : VkComponent(name)
           {
              // Load any class-defaulted resources
              // for this object

              setDefaultResources(parent,
                                  _defaultColorChoiceResources );

              // Create an unmanaged widget as the top
              // of the widget hierarchy

              _baseWidget =  XtVaCreateWidget ( _name,
                                                xmFrameWidgetClass,
                                                parent,
                                                NULL ) ;

              // install a callback to guard against
              // unexpected widget destruction

              installDestroyHandler();


              // Create widgets used in this component
              // All variables are data members of this class

              _radioBox = XmCreateRadioBox( _baseWidget,
                                            "radioBox",
                                            NULL, 0 );
              XtManageChild( _radioBox );


              _red = XtVaCreateManagedWidget  ( "red",
                                        xmToggleButtonWidgetClass,
                                        _radioBox,
                                        NULL ) ;

              XtAddCallback ( _red,
                              XmNvalueChangedCallback,
                              &ColorChoice::newColorCallback,
                              (XtPointer) this );

              _green = XtVaCreateManagedWidget  ( "green",
                                        xmToggleButtonWidgetClass,
                                        _radioBox,
                                        NULL ) ;

              XtAddCallback ( _green,
                              XmNvalueChangedCallback,
                              &ColorChoice::newColorCallback,
                              (XtPointer) this );

              _blue = XtVaCreateManagedWidget  ( "blue",
                                                xmToggleButtonWidgetClass,
                                                _radioBox,
                                                XmNset, TRUE,
                                                NULL ) ;
              XtAddCallback ( _blue,
                               XmNvalueChangedCallback,
                               &ColorChoice::newColorCallback,
                               (XtPointer) this );
           }

           ColorChoice::~ColorChoice()
           {
              // Empty Destructor. Base class destroys widgets
           }

           const char* ColorChoice::className()
           {
              return ("ColorChoice");
           }

           void ColorChoice::newColorCallback (Widget w,
                                      XtPointer clientData,
                                      XtPointer callData)
           {
              ColorChoice* obj = (ColorChoice*) clientData;

              obj->newColor(w, callData);
           }

           void ColorChoice::newColor(Widget w,
                                      XtPointer callData )
           {
              Color chosenColor;
              XmToggleButtonCallbackStruct *cbs =
                   (XmToggleButtonCallbackStruct*) callData;

              if(cbs->set)
              {
                  if(w == _red) chosenColor = RED;
                  else if(w == _blue) chosenColor = BLUE;
                  else if(w == _green) chosenColor = GREEN;

                  callCallbacks(colorChangedCallback,
                                (void *) chosenColor);
              }
           }



   A Subclassing Example
     The following example illustrates how subclassing can be used to modify
     the behavior of a component. This example changes the ColorChoice
     component shown above by allowing multiple colors to be chosen at once.

           //////////////////////////////////////////////////////////////
           // Header file for ColorChoices a subclass template
           //////////////////////////////////////////////////////////////
           #ifndef _COLORCHOICES_H
           #define _COLORCHOICES_H

           #include "ColorChoice.h"

           class ColorChoices : public ColorChoice
           {

            protected:

            public:

              ColorChoices(const char *, Widget);
              ~ColorChoices();
              const char* className();
           };
           #endif

           /////////////////////////////////////////////////////////////
           // Source file for ColorChoices
           /////////////////////////////////////////////////////////////

           #include "ColorChoices.h"

           ColorChoices::ColorChoices(const char *name,
                                      Widget parent) :
                   ColorChoice(name, parent)
           {
                  XtVaSetValues(_radioBox, XmNradioBehavior, FALSE, NULL);
           }

           ColorChoices::~ColorChoices()
           {
               // Empty
            }

           const char* ColorChoices::className()
           {
              return ("ColorChoices");
           }


INHERITED MEMBER FUNCTIONS
   Inherited from VkCallbackObject
          callCallbacks(), addCallback(), removeCallback(),
          removeAllCallbacks()

KNOWN DERIVED CLASSES
     VkComponentList, VkApp, VkMsgApp, VkSimpleWindow, VkWindow, VkForkDoc,
     VkMsgWindow, VkDialogManager, VkBusyDialog, VkInterruptDialog,
     VkErrorDialog, VkFatalErrorDialog, VkFileSelectionDialog,
     VkWarningDialog, VkGenericDialog, VkPrefDialog, VkInfoDialog,
     VkQuestionDialog, VkToggleList, VkMenuItem, VkMenuAction,
     VkMenuConfirmFirstAction, VkMenuActionObject, VkMenuActionWidget,
     VkMenuToggle, VkMenuUndoManager, VkMenuLabel, VkMenuSeparator, VkMenu,
     VkOptionMenu, VkSubMenu, VkHelpPane, VkRadioSubMenu, VkMenuBar,
     VkPopupMenu, VkTextIO, VkForkIO, VkCheckBox, VkRadioBox,
     VkCompletionField, VkDoubleBuffer, VkMeter, VkPie, VkDropSite, VkGraph,
     VkNode, VkPeriodic, VkOutline, VkOutlineASB, VkPackTight, VkPrefItem,
     VkPrefGroup, VkPrefList, VkPrefRadio, VkPrefText, VkPrefToggle,
     VkPrefOption, VkPrefCustom, VkPrefEmpty, VkPrefLabel, VkPrefSeparator,
     VkRepeatButton, VkResizer, VkScroll, VkMsgComponent

BUGS
SEE ALSO
     VkCallbackObject, VkComponentList
     ViewKit Programmer's Guide
     The X Window System, DEC Press, Bob Sheifler and Jim Gettys
     The X Window System Toolkit, DEC Press, Paul Asente and Ralph Swick
     The OSF/Motif Programmers Reference, Prentice Hall, OSF