VkComponent(3x)
VkComponent - Abstract base class for all ViewKit components
As shipped in IRIX 6.5.5. 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