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



Recommended Resources for Compound String Widgets

Any Motif widget displaying a compound string should support at least the following resources:

  1. A resource whose value holds the render table.

  2. A resource whose value holds the compound string itself.

  3. A resource whose value specifies the alignment of the text within the widget.

  4. A resource whose value determines the layout direction of the text. That is, this resource tells the widget whether the text should read from left to right or from right to left.

    It is not a requirement that each widget define all of these resources. In fact, many of these resources will be provided by the widget's superclass. However, each widget displaying text needs to examine the values of these resources and display the text accordingly.

    The following subsections examine how the ExmString demonstration widget uses these four resources.

  5. The Render Table Resource

    The render table resource holds the value of the render table that is used to display the text. All render table resources should have a representation type of XmRRenderTable.

    Some Motif widgets call this resource XmNrenderTable. However, you may wish to provide a somewhat more specialized name for this resource. For example, if you are writing a widget named MyGraph, the render table resource could be called MyNgraphRenderTable.

    In order to be consistent with other Motif widgets, the render table resource should set its default value through an XtRCallProc procedure rather than through XmRImmediate data. The XtRCallProc procedure for the ExmString widget is called DefaultFont, and it is defined as follows:

    static void
    DefaultFont (
            Widget w,
            int offset,
            XrmValue *value
    )
    {
     ExmStringWidgetClass wc = (ExmStringWidgetClass)XtClass(w);
     static XmRenderTable  f1;
     
     /* Find the default render table associated with the default
        render table type. */
       f1 = XmeGetDefaultRenderTable(w,
                         wc->string_class.default_render_table_type);
     
       value->addr = (XtPointer)&f1;
       value->size = sizeof(f1);
    }

    The XmeGetDefaultRenderTable routine finds the default render table. The second argument to XmeGetDefaultRenderTable specifies the default render table type. This field must contain one of the following three values:

    1. XmLABEL_RENDER_TABLE

    2. XmBUTTON_RENDER_TABLE

    3. XmTEXT_RENDER_TABLE

      ExmString stores the default render table type in a field of the String class record. For the ExmString widget, the default render table type is to XmLABEL_RENDER_TABLE. However, subclasses of ExmString may override this value. For example, the ExmCommandButton widget sets its default render table type to XmBUTTON_RENDER_TABLE.

      See the reference page for XmeGetDefaultRenderTable in Chapter 17 for more details.

    4. The Compound String Resource

      The compound string resource holds the compound string itself. Compound string resources should have a representation type of XmRXmString.

      When a user accesses a compound string resource by calling XtGetValue, your widget must return a copy of the compound string resource's value. That is, your widget must make a copy of the string resource value, probably by calling XmStringCopy. Then, your widget must return a pointer to this copy rather than returning the original. Your widget should use Motif's syn_resource mechanism to handle this requirement.

      For example, the ExmString widget provides a resource named ExmNcompoundString that holds the value of one compound string. Therefore, ExmString provides the following synthetic resource array:

      static XmSyntheticResource syn_resources[] =
      {
         {
              ExmNcompoundString,
              sizeof(XmString),
              XtOffsetOf(ExmStringRec, string.compound_string),
              GetValuesCompoundString,
              NULL
         }
      };

      The preceding declaration tells Motif to call the GetValuesCompoundString routine prior to returning the value of ExmNcompoundString. The GetValuesCompoundString routine is as follows:

      GetValuesCompoundString(
              Widget w,
              int resource,   /* unused */
              XtArgVal *value)
      {
       ExmStringWidget sw = (ExmStringWidget) w;
       XmString  string;
       
       /* All Motif widgets are responsible for making a copy of an XmString
          resource whenever an application accesses the resource through a
      call
          to XtGetValues. */
         string = XmStringCopy(sw->string.compound_string);
       
         *value = (XtArgVal) string;
      }

      The Alignment Resource

      The alignment resource holds a value that symbolizes the justification of the text. The alignment resource should have a representation type of XmRAlignment. The valid values for this representation type are documented in the XmLabel reference page, under the description of the XmNalignment resource. (See the Motif Programmer's Reference for XmLabel(3x).)

      The positioning of text within your widget should depend on a combination of the alignment resource and the layout direction resource. (See the next section for details.)

      The Layout Direction Resource

      Your widget should examine the layout direction resource provided by XmPrimitive or XmManager. We do not recommend creating your own layout direction resource. The XmManager and XmPrimitive widgets both provide an XmNlayoutDirection resource, and your widget should probably not override this value.

      The combination of the layout direction resource and the alignment resource should determine the layout and alignment of the text. For example, suppose the value of the alignment resource is XmALIGNMENT_BEGINNING and the value of the layout direction resource is XmLEFT_TO_RIGHT. In this case, the left sides of the lines of text should be vertically aligned with the left edge of the widget window. On the other hand, if the layout direction value changes to XmRIGHT_TO_LEFT, then the right sides of the lines of text should be vertically aligned with the right edge of the widget window.

      The AlignmentDirection method of the ExmString widget demonstrates how to determine where the text starts. The starting location of the text is particularly important for the resize method of ExmString. The text will be positioned in one of the following ways:

      1. The text will be centered.

      2. The text will start at the left side of the widget.

      3. The text will start at the right side of the widget.

        The following is the code for the AlignmentDirection method:

        static void
        AlignmentDirection(
                Widget w)
        {
         ExmStringWidget sw = (ExmStringWidget)w;
         
           if (sw->string.alignment == XmALIGNMENT_CENTER)
           /* The text will be centered. */
             sw->string.text_starts_here = ExmCENTER_STRING;
         
           else if (
               (XmDirectionMatch(sw->primitive.layout_direction,
        XmLEFT_TO_RIGHT) &&
                sw->string.alignment == XmALIGNMENT_BEGINNING)
                                        ||
               (XmDirectionMatch(sw->primitive.layout_direction,
        XmRIGHT_TO_LEFT) &&
                sw->string.alignment == XmALIGNMENT_END))
           /* The string will start at the left side of the widget. */
             sw->string.text_starts_here = ExmSTART_STRING_LEFT_SIDE;
         
           else if (
               (XmDirectionMatch(sw->primitive.layout_direction,
        XmLEFT_TO_RIGHT) &&
                sw->string.alignment == XmALIGNMENT_END)
                                        ||
               (XmDirectionMatch(sw->primitive.layout_direction,
        XmRIGHT_TO_LEFT) &&
                sw->string.alignment == XmALIGNMENT_BEGINNING))
           /* The string will start at the right side of the widget. */
             sw->string.text_starts_here = ExmSTART_STRING_RIGHT_SIDE;
        }

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