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



The PrimitiveClassPart Structure

The PrimitiveClassPart structure is the second chunk of the widget class record. In the PrimitiveClassPart structure, you must define values for seven different fields. For example, following is the PrimitiveClassPart structure of the ExmSimple widget:

{
 /* border_highlight */           XmInheritBorderHighlight,
 /* border_unhighlight */         XmInheritBorderUnhighlight,
 /* translations */               XtInheritTranslations,
 /* arm_and_activate */           NULL,
 /* syn_resources */              syn_resources,
 /* num_syn_resources */          XtNumber(syn_resources),
 /* extension */                  (XtPointer)&primClassExtRec,
},

The following subsections detail the fields of the PrimitiveClassPart structure.

The border_highlight Field

The border_highlight field holds the name of a method that highlights the perimeter of the widget. The border_highlight method is typically called by the Redisplay method.

You should probably set the border_highlight field to one of the following:

  1. The name of your widget's border_highlight method

  2. XmInheritBorderHighlight, to indicate that you are inheriting the border_highlight method of your superclass

    Most primitive widgets should inherit the border_highlight method of XmPrimitive. The border_highlight method of XmPrimitive provides the standard Motif highlighting style for primitive widgets. In particular, the border_highlight method of XmPrimitive does the following:

    1. Sets the value of internal field primitive.highlighted to True.

    2. Examines the widget's dimensions and resources to determine whether or not the widget needs a border. For example, there is no need to draw a border if the value of the XmNhighlightThickness resource is 0.

    3. If the widget does need a border, the method draws it. The drawing characteristics (color, pixmap, and so forth) are governed by the GC stored in instance data member primitive.highlight_GC.

      If you do write your own border_highlight method, it must have the following prototype:

      void BorderHighlight(
              Widget  w)

      where widget specifies the widget ID.

      If you do write your own border_highlight method, you should probably use the XmeDrawHighlight function to draw the border highlight. In addition, your border_highlight method must set the value of instance data member primitive.highlighted to True immediately after drawing the border highlight.

      The ExmTabButton and ExmMenuButton widgets both have special requirements for border highlights. Therefore, both of these widgets provide their own border_highlight methods rather than inherit them.

    4. The border_unhighlight Field

      The border_unhighlight field holds the name of a method that removes a widget's border. For example, if your primitive widget has a different background color than its parent, then it may be wise to remove the border (possibly in preparation for a redraw of the border). You should probably set the border_unhighlight field to one of the following:

      1. XmInheritBorderUnhighlight, to inherit the border_unhighlight method of your superclass. The XmPrimitive widget provides a border_unhighlight method, which your primitive widget can inherit.

      2. The name of your widget's border_unhighlight method.

        If the border_highlight field of your widget is set to XmInheritBorderHighlight, then you should set the border_unhighlight field to XmInheritBorderUnhighlight.

        The border_unhighlight method of XmPrimitive does the following:

        1. Sets the value of internal field primitive.highlighted to False.

        2. Examines the widget's dimensions and resources to determine whether or not there is indeed a border to erase.

        3. If the widget does have a border, the border_unhighlight method calls an internal function that unhighlights the border.

          If you do write your own border_unhighlight method, it must have the following prototype:

          void BorderUnhighlight(
                  Widget  w)

          where widget specifies the widget ID.

          If your widget provides its own border_unhighlight method, then it must set the value of instance data member primitive.highlighted to False. To remove highlights, your method should probably call the same internal function that drew the highlights, namely, XmeDrawHighlight . One trick to unhighlighting is to paint over the existing highlight with the background color and background pixmap of your widget's parent. Your widget's parent stores its background color and background pixmap in the manager.background_GC instance data member.

        4. The translations Field

          The translations field holds a string that implements your widget's keyboard traversals. The complete keyboard traversal policy depends not only on the value of the translations field but also on the values of two resources.

          You can set this field to one of the following:

          1. XtInheritTranslations, to inherit the traversal translations string of your superclass. The XmPrimitive widget provides a traversal translations string that your widget can inherit.

          2. The name of your widget's own traveral translations string.

          3. NULL, to indicate the absence of any traversal translations.

            (See Chapter 7 for details.)

          4. The arm_and_activate Field

            The arm_and_activate field holds the name of a method that is activated by an osfActivate event. The named method must provide the visual simulation of a push button being pushed in as a response to the osfActivate event.

            Your widget should specify one of the following for the arm_and_activate field:

            1. The name of your widget's arm_and_activate method.

            2. XmInheritArmAndActivate, to inherit the arm_and_activate method of your superclass. The XmPrimitive widget does not provide an arm_and_activate method, so you cannot inherit from it.

            3. NULL, to indicate the absence of an arm_and_activate method.

              In the standard Motif widget set, all the button widgets provide an arm_and_activate method. All other primitive widgets set this field to NULL.

              The ExmCommandButton widget provides the following arm_and_activate method:

              static void
              ArmAndActivate (
                     Widget w,
                     XEvent *event,
                     String *params,
                     Cardinal *num_params)
              {
                 ExmCommandButtonWidgetClass wc =
              (ExmCommandButtonWidgetClass)XtClass(w);
                 ExmCommandButtonWidget cw = (ExmCommandButtonWidget)w;
                 XmAnyCallbackStruct cb;
                 /* Call DrawShadow. */
                   cw->command_button.visual_armed = True;
                   if (wc->simple_class.draw_shadow)
                     (*(wc->simple_class.draw_shadow)) (w);
               
              /* Eliminate any data waiting in the X Window's output buffer. */
                XFlush (XtDisplay (cw));
               
              /* Assuming that the XmNactivateCallback resource is set, call the
                 callback routine. */
                if (cw->command_button.activate_callback) {
                  cb.reason = XmCR_ACTIVATE;
                  cb.event = event;
                  XtCallCallbackList((Widget)cw, cw->command_button.activate_callback,
              &cb);
                }
               
              /* Provide a short delay prior to the appearance of any new windows
              created
                 by the callback. The net effect is that the ExmCommandButton will
              appear
                 to flash on and off immediately prior to the appearance of any window
              that
                 may overwrite it. */
                if ((cw->core.being_destroyed == False) &&
                    (cw->command_button.visual_timer == 0))
                  cw->command_button.visual_timer =
                    XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)cw),
                                  (unsigned long) VISUAL_DELAY,
                                   VisualDisarm, /* method that disarms */
                                  (XtPointer)(cw)); /* pass this widget to
              VisualDisarm */
              }

            4. The syn_resources Field

              The syn_resources field holds the name of the array that defines the widget's synthetic resources. Synthetic resources provide a mechanism for translating widget resource values between different formats. (See Chapter 6 for information on synthetic resources.)

              Most primitive widgets in the standard Motif widget set provide a syn_resources array.

              If you do not wish to define synthetic resources for your widget, set the value of this field to NULL.

              The num_syn_resources Field

              The num_syn_resources field holds the number of synthetic resources defined by the array in the syn_resources field. If your widget does not provide a syn_resources array, then you should specify 0 for the num_syn_resources field. If your widget does provide a syn_resources array, then your widget should use the the XtNumber macro to count these resources.

              The extension Field

              Nearly every primitive widget displays text or graphics. Any widget that does must specify a primitive class extension record. The extension field holds an XtPointer to the name of this record. You should always name your primitive class extension record primClassExtRec; for example:

              /* extension */                 
              (XtPointer)&primClassExtRec,

              If your primitive widget does not display any text or graphics, then you should set the extensions field to NULL. If your primitive widget does need to define an extension record, see the next section for details.


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