[ Previous | Next | Contents | Glossary | Home | Search ]
Motif 2.1 Widget Writer's Guide



Installing a Trait

You must perform the following steps in order to install a trait on a widget:

  1. Include the appropriate header file for the trait you are using.

  2. Declare the trait structure variable.

  3. Call the XmeTraitSet function.

  4. Write the code for any trait methods named in the trait structure variable.

    The coding for all four steps is to be added to the widget source code file. That is, you do not need to make any changes to the widget's header files.

    The following subsections examine these four activities by focusing on how the XmQTaccessTextual trait is installed on the ExmString widget.

  5. Step 1: Include the Appropriate Header Files

    If you plan to install a trait in your widget, then your widget source code file must include the appropriate trait header files. Every widget that installs one or more traits must include the general-purpose trait header file TraitP.h. In addition, depending on which traits are being installed, the widget source code file must also include the appropriate trait-specific header file documented in the reference pages of Chapter 19.

    For example, the widget source code file (String.c) for the ExmString widget contains the following three declarations:

    #include <Xm/TraitP.h>
    #include <Xm/AccTextT.h>
    #include <Xm/SpecRenderT.h>

    The Xm/AccTextT.h header file is included because ExmString installs the XmQTaccessTextual trait. In addition, the Xm/SpecRenderT.h header file is included because ExmString also uses the XmQTspecifyRenderTable trait.

    Step 2: Declare the Trait Structure Variable

    You must declare a trait structure variable for every trait that you plan to install. You should place this declaration in the source code file after the class record declaration but before the first widget method.

    The data type of a trait structure variable must be the trait structure associated with the trait. (See Chapter 19 to find the relevant trait structure for your trait.) For example, the trait structure associated with the XmQTaccessTextual trait is XmAccessTextualTraitRec.

    Motif recommends giving the trait structure variable a name that consists of the widget name followed by an acronym that symbolizes the trait. For example, ExmString uses the variable name StringATT to identify its XmQTaccessTextual trait structure variable.

    All trait structure variable declarations should be prefixed with static XmConst. (See Chapter 2 for details about XmConst.)

    For example, the ExmString widget declares a trait structure variable for the XmQTaccessTextual trait as follows:

    static XmConst XmAccessTextualTraitRec StringATT = {
      0,                       /* version */
      StringGetValue,          /* trait method */
      StringSetValue,          /* trait method */
      StringPreferredFormat,   /* trait method */
    };

    The preceding declaration declares a trait structure variable named StringATT. This variable has data type XmAccessTextualTraitRec. This data type is defined in the AccTextT.h trait header file.

    The first field of all trait structure variables is the version field. You must always specify an integer value for this field. At Motif Release 2.0, none of the standard Motif traits make any attempt to interpret the value in the version field. However, at Motif Release 2.0, you must set the version field to 0 since future releases of Motif may use the version field.

    The remaining fields following the version field specify the names of the trait methods. By convention, the trait method names in your trait structure variables should correspond to the trait method names documented in the reference pages of Chapter 19. However, your trait method names should eliminate underscores and should capitalize the first letter of every word. For example, we named the second trait method StringSetValue because the trait method name string_set_value is documented in the XmQTaccessTextual trait reference page of Chapter 19.

    Some traits allow you to omit certain trait methods. (See the individual reference pages of Chapter 19 for details.) To tell Motif that you are omitting a certain trait method, simply mark the appropriate field in the trait structure record as being NULL. For example, if we did not provide a StringSetValue method in the ExmSimple widget, the preceding declaration would have looked like this:

    static XmConst XmAccessTextualTraitRec StringATT = {m
    0,                         /* version */m
    StringGetValue,            /* trait method */m
    NULL,                      /* not providing this trait method */m
    StringPreferredFormat,     /* trait method */
    };

    Step 3: Call XmeTraitSet

    Call the XmeTraitSet function to install a trait on a widget class. Typically, your widget calls XmeTraitSet from the class_part_initialize method. By so doing, the trait is installed not only on the current widget, but also on all of its subclasses. If you want the trait installed on the current widget class only (and not its subclasses), then you should call XmeTraitSet from the class_initialize method instead of the class_part_initialize method.

    For example, ExmString calls XmeTraitSet to install the XmQTaccessTextual trait as follows:

    XmeTraitSet((XtPointer) widgetclass, XmQTaccessTextual,
               (XtPointer) &StringATT);

    The third argument to XmeTraitSet holds the address of the trait structure variable created in Step 2.

    Because the call to XmeTraitSet took place in the class_part_initialize method, Motif installs this trait on ExmString and on all its subclasses.

    In some cases, you may not want the widget you are writing to inherit some of the installed traits of its superclasses. For these situations, you can prevent trait inheritance by specifying NULL as the third argument to XmeTraitSet. For example, suppose you are writing a subclass of ExmString, named ExmStringSubclass. If you do not want ExmStringSubclass to install ExmQTaccessTextualTrait, the class_part_initialize method of ExmStringSubclass should call XmeTraitSet as follows:

    XmeTraitSet((XtPointer) widgetclass, XmQTaccessTextual,
    NULL);

    Step 4: Writing Trait Methods

    A trait method is a function that is callable by another widget, even if that other widget is not a subclass of the current widget. Typically, the caller is either the parent widget or the child widget of the current widget.

    For example, the XmQTaccessTextual trait defines three trait methods. The simplest trait method, StringPreferredFormat, is shown as follows:

    static int
    StringPreferredFormat(
            Widget  w)
    {
    /* Choose XmFORMAT_XmSTRING because the ExmString widget holds its
    displayed
       text in XmString format (as opposed to Multibyte or WCS format). */
            return(XmFORMAT_XmSTRING);
    }

    By convention, you should place your widget's trait methods toward the end of your widget source code file, immediately prior to the publicly accessible functions.


    [ Previous | Next | Contents | Glossary | Home | Search ]