Subsections

The Scale Widget

   

The Scale widget allows the user to input numeric values into a program. An example of the Scale widget is shown in Fig. 12.1.

 

Fig. 12.1 Output of scale.c

Scale basics

 

To create a Scale Widget use XtVaCreateManagedWidget() , with a
xmScaleWidgetClass  class pointer or use XmCreateScale() . Once again a header file, <Xm/Scale.h>, needs to be included in all programs using Scale widgets.

The following Scale Widget Resources  are typically used:

XmNmaximum
  -- The largest value of scale.
XmNminimum
  -- The scale's smallest value. The default value is 0.
XmNorientation
  -- XmHORIZONTAL or XmVERTICAL, resource values define how the Scale is displayed.
XmNtitleString
  -- The XmString label of the scale.
XmNdecimalPoints
  -- A scale value is always returned as an integer (default 0). This resource can be set to give the user the impression of floating point input, e.g. if we have a range 0 - 1000 on the Scale but XmNdecimalPoints set to 2. The displayed range would be 0.00 - 10.00.

The application programmer must take care of the input value to the program. In the above a value will still get returned in the integer range and somewhere in the application there must be a division by 100.

XmNshowValue
  -- True or False. This resource decides whether or not to display the value of the scale as it moves.

XmNvalue
  -- The current value (int) of the Scale.

XmNprocessingDirection
  -- Either XmMAX_ON_TOP, XmMAX_ON_BOTTOM,
XmMAX_ON_LEFT
or XmMAX_ON_RIGHT. This resource sets the end of the scale, where the maximum and minimum values are placed. This depends on the orientation of the Scale.

Scale Callbacks

 

The Scale callback can be called for two types of events:

XmNvalueChangedCallback
  -- If the value is changed.
XmNdragCallback
  -- If the Scale value is moved at all, ``continuous'' values can be input. Note: This may affect X performance as it involves instantaneously updating the display of the scale.

The Scale callback function is standard:



void scale_cbk(Widget w, XtPointer data, 
               XmScaleCallbackStruct *struct)
 



The structure element value holds the current Scale integer value, and is the only structure element that is really of interest. The scale.c program illustrates this usage.

The scale.c program

  

The program simply brings up a virtual volume Scale (in the context of a virtual amplifier controller). The user changes the value which is caught by a XmNvalueChangedCallback and the current value is interrogated to print a message to standard output.

#include  <Xm/Xm.h>
#include <Xm/Scale.h>

/* Prototype callback  */

void scale_cbk(Widget , int , 
               XmScaleCallbackStruct *);

main(int argc, char **argv)

{   Widget        top_wid, scale;
    XmString	  title;
    XtAppContext  app;
    
 
    top_wid = XtVaAppInitialize(&app, "Scale_eg", NULL, 0,
        &argc, argv, NULL, NULL);
        
    title = XmStringCreateLocalized("Volume");

    scale = XtVaCreateManagedWidget("scale",
        xmScaleWidgetClass, top_wid,
        XmNtitleString,   title,
        XmNorientation,    XmHORIZONTAL,
        XmNmaximum,       11,
        XmNdecimalPoints, 0,
        XmNshowValue,     True,
        XmNwidth,         200,
        XmNheight,        100,
        NULL);
     
    XtAddCallback(scale,XmNvalueChangedCallback, scale_cbk, 
                  NULL);
 
    XtRealizeWidget(top_wid);
    XtAppMainLoop(app);
}


void scale_cbk(Widget widget, int data, 
               XmScaleCallbackStruct *scale_struct)

{    if (scale_struct->value < 4)
       printf("Volume too quiet (%d)\n");
    else if (scale_struct->value < 7)
       printf("Volume Ok (%d)\n"); 
    
     else
        if (scale_struct->value < 10)
       printf("Volume too loud (%d)\n");
      else /* Volume == 11 */
       printf("Volume VERY Loud (%d)\n");       
}

Scale Style

 

Motif 1.2 Style

The Motif Style Guide (Chapter 18) suggests that some sort of markers should be used to gauge distance along a Scale. However, no provision is made for this within the Scale widget class in Motif 1.2. Instead, the programmer must assemble this manually. An assortment of labels and tics can be used to provide some sort of visual ruler (Fig. 12.2).

 

Fig. 12.2 Better Style Scale Output

The Motif program code that achieves this, by placing vertical SeparatorGadgets  (``$\mid$'') at equally spaced intervals, is as follows:

Widget ...,tics[1];

.......

.......
 
/* label scale axis */
    for (i=0; i < 11; ++i )
      {  XtSetArg(args[0], XmNseparatorType, XmSINGLE_LINE);
         XtSetArg(args[1], XmNorientation, XmVERTICAL);
         XtSetArg(args[2], XmNwidth, 10);
         XtSetArg(args[3], XmNheight, 5);
         tics[i] = XmCreateSeparatorGadget(scale, "|", 
                 args, 4);
      }
    
    XtManageChildren(tics, 11);

...........
...........

The Motif 2.0 Style

Motif 2.O provides a new convenience function XmScaleSetTicks() to allow for an easier configuration of ticks along the Scale widget. The configuration allows for three different sized ticks to be placed at specified regular intervals along the Scale. Each tick mark is actually a SeparatorGadget  oriented perpendicular to the Scale's orientation. The function XmScaleSetTicks() takes seven arguments:

Widget
-- The scale widget being assigned the ticks.
int large_every
-- The number of Scale values between large ticks.
int num_medium
-- The number of medium ticks between large ticks.
int num_small
-- The number of small ticks between medium ticks.
Dimension size_large
-- The size (width or height) of the big ticks.
Dimension size_medium
-- The size (width or height) of the medium ticks.
Dimension size_small
-- The size (width or height) of the small ticks.

If you specify tick marks for a Scale and then change the Scale's orientation then you must remove all the tick marks and then recreate new ones in the correct orientation. This may be achieved by the following method:



Dave Marshall
1/5/1999