VkComponent(3x) VkComponent(3x)
VkComponent - Abstract base class for all ViewKit components
VkCallbackObject
#include <Vk/VkComponent.h>
PUBLIC PROTOCOL SUMMARY
Displaying Components
virtual void show()
virtual void hide()
void manage()
void unmanage()
Destructor [Toc] [Back]
virtual ~VkComponent()
Access Functions [Toc] [Back]
char * name() const
virtual const char *className();
Widget baseWidget() const
virtual operator Widget();
Access Functions - ViewKit 2.1 only [Toc] [Back]
VkScreen *getScreen();
Supported Callbacks [Toc] [Back]
static const char * const deleteCallback
Utility Functions [Toc] [Back]
virtual Boolean okToQuit()
virtual void afterRealizeHook()
static Boolean isComponent(VkComponent *comp)
Dynamic Loading Support [Toc] [Back]
static VkComponent *loadObject(const char *name,
Widget parent,
const char *className,
const char *filename);
Page 1
VkComponent(3x) VkComponent(3x)
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 [Toc] [Back] Handling Widget Destruction
void installDestroyHandler();
void removeDestroyHandler();
virtual void widgetDestroyed();
Resource Support [Toc] [Back]
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 [Toc] [Back]
VkComponent( const char *name );
VkComponent();
Deriving Subclasses [Toc] [Back]
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.
Page 2
VkComponent(3x) VkComponent(3x)
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 [Toc] [Back] VkComponent
Page 3
VkComponent(3x) VkComponent(3x)
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 );
Page 4
VkComponent(3x) VkComponent(3x)
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 ) ;
Page 5
VkComponent(3x) VkComponent(3x)
// 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 [] = {
Page 6
VkComponent(3x) VkComponent(3x)
{
"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;
Page 7
VkComponent(3x) VkComponent(3x)
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
Page 8
VkComponent(3x) VkComponent(3x)
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);
Page 9
VkComponent(3x) VkComponent(3x)
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.
Page 10
VkComponent(3x) VkComponent(3x)
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",
Page 11
VkComponent(3x) VkComponent(3x)
"liblbtext.so");
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);
Page 12
VkComponent(3x) VkComponent(3x)
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
Page 13
VkComponent(3x) VkComponent(3x)
// 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,
Page 14
VkComponent(3x) VkComponent(3x)
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 [Toc] [Back]
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.
Page 15
VkComponent(3x) VkComponent(3x)
//////////////////////////////////////////////////////////////
// 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 [Toc] [Back] Inherited from VkCallbackObject
callCallbacks(), addCallback(), removeCallback(),
removeAllCallbacks()
Page 16
VkComponent(3x) VkComponent(3x)
KNOWN DERIVED CLASSES [Toc] [Back] 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
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
PPPPaaaaggggeeee 11117777 [ Back ]
|