(3)

NAME
XfwfToggle

DESCRIPTION
The XfwfToggle is a button that switches states with every activation (which is by default with every mouse click). The states are named `on' and `off'. The states can be indicated with a $urd$ before the label Two callbacks report the changed state to the application: onCallback is called when the button switches to `on', offCallback is called when the button switches back to `off'.

  Public variables
XfwfToggle
Name | Class | Type | Default
XtNonCallback | XtCOnCallback | Callback | NULL
XtNoffCallback | XtCOffCallback | Callback | NULL
XtNon | XtCOn | Boolean | False
XtNonIcon | XtCOnIcon | Icon * | "filledsquare"
XtNoffIcon | XtCOffIcon | Icon * | "emptysquare"

XtNonCallback
    The onCallback is called by the toggle action or by the switch_on action, if the previous state was `off'. The call_data argument will contain the XEvent pointer that trigerred the action function.

    <Callback> XtCallbackList onCallback = NULL

XtNoffCallback
    The offCallback is called from the toggle or switch_off action, if the previous state was `on'. The call_data argument will be a pointer to the XEvent that caused the action.

    <Callback> XtCallbackList offCallback = NULL

XtNon
    The variable on records the state of the widget: True means `on' and False means `off'.

    Boolean on = False

XtNonIcon
    By default, the button displays a $urd$ when on and nothing when off. The two resources onIcon and offPIcon can replace these two graphics with arbitrary pixmaps. Suggested size for these pixmaps is about $16 imes18$.

    Icon * onIcon = <String>"filledsquare"

XtNoffIcon
    The offIcon is displayed when the button is in `off' state. By default, nothing is displayed in this state.

    Icon * offIcon = <String>"emptysquare"
    XfwfButton
    Name | Class | Type | Default
    XtNactivate | XtCActivate | Callback | NULL
    XtNenter | XtCEnter | Callback | NULL
    XtNleave | XtCLeave | Callback | NULL
    XfwfLabel
    Name | Class | Type | Default
    XtNlabel | XtCLabel | String | NULL
    XtNtablist | XtCTablist | String | NULL
    XtNfont | XtCFont | FontStruct | XtDefaultFont
    XtNforeground | XtCForeground | Pixel | XtDefaultForeground
    XtNhlForeground | XtCHlForeground | Pixel | XtDefaultForeground
    XtNalignment | XtCAlignment | Alignment | 0
    XtNtopMargin | XtCTopMargin | Dimension | 2
    XtNbottomMargin | XtCBottomMargin | Dimension | 2
    XtNleftMargin | XtCLeftMargin | Dimension | 2
    XtNrightMargin | XtCRightMargin | Dimension | 2
    XtNshrinkToFit | XtCShrinkToFit | Boolean | False
    XtNrvStart | XtCRvStart | Int | 0
    XtNrvLength | XtCRvLength | Int | 0
    XtNhlStart | XtCHlStart | Int | 0
    XtNhlLength | XtCHlLength | Int | 0
    XfwfBoard
    Name | Class | Type | Default
    XtNabs_x | XtCAbs_x | Position | 0
    XtNrel_x | XtCRel_x | Float | "0.0"
    XtNabs_y | XtCAbs_y | Position | 0
    XtNrel_y | XtCRel_y | Float | "0.0"
    XtNabs_width | XtCAbs_width | Position | 0
    XtNrel_width | XtCRel_width | Float | "1.0"
    XtNabs_height | XtCAbs_height | Position | 0
    XtNrel_height | XtCRel_height | Float | "1.0"
    XtNhunit | XtCHunit | Float | "1.0"
    XtNvunit | XtCVunit | Float | "1.0"
    XtNlocation | XtCLocation | String | NULL
    XfwfFrame
    Name | Class | Type | Default
    XtNcursor | XtCCursor | Cursor | None
    XtNframeType | XtCFrameType | FrameType | XfwfRaised
    XtNframeWidth | XtCFrameWidth | Dimension | 0
    XtNouterOffset | XtCOuterOffset | Dimension | 0
    XtNinnerOffset | XtCInnerOffset | Dimension | 0
    XtNshadowScheme | XtCShadowScheme | ShadowScheme | XfwfAuto
    XtNtopShadowColor | XtCTopShadowColor | Pixel | compute_topcolor
    XtNbottomShadowColor | XtCBottomShadowColor | Pixel | compute_bottomcolor
    XtNtopShadowStipple | XtCTopShadowStipple | Bitmap | NULL
    XtNbottomShadowStipple | XtCBottomShadowStipple | Bitmap | NULL
    XfwfCommon
    Name | Class | Type | Default
    XtNtraversalOn | XtCTraversalOn | Boolean | True
    XtNhighlightThickness | XtCHighlightThickness | Dimension | 2
    XtNhighlightColor | XtCHighlightColor | Pixel | XtDefaultForeground
    XtNhighlightPixmap | XtCHighlightPixmap | Pixmap | None
    XtNnextTop | XtCNextTop | Callback | NULL
    XtNuserData | XtCUserData | Pointer | NULL
    Composite
    Name | Class | Type | Default
    XtNchildren | XtCChildren | WidgetList | NULL
    insertPosition | XtCInsertPosition | XTOrderProc | NULL
    numChildren | XtCNumChildren | Cardinal | 0
    Core
    Name | Class | Type | Default
    XtNx | XtCX | Position | 0
    XtNy | XtCY | Position | 0
    XtNwidth | XtCWidth | Dimension | 0
    XtNheight | XtCHeight | Dimension | 0
    borderWidth | XtCBorderWidth | Dimension | 0
    XtNcolormap | XtCColormap | Colormap | NULL
    XtNdepth | XtCDepth | Int | 0
    destroyCallback | XtCDestroyCallback | XTCallbackList | NULL
    XtNsensitive | XtCSensitive | Boolean | True
    XtNtm | XtCTm | XTTMRec | NULL
    ancestorSensitive | XtCAncestorSensitive | Boolean | False
    accelerators | XtCAccelerators | XTTranslations | NULL
    borderColor | XtCBorderColor | Pixel | 0
    borderPixmap | XtCBorderPixmap | Pixmap | NULL
    background | XtCBackground | Pixel | 0
    backgroundPixmap | XtCBackgroundPixmap | Pixmap | NULL
    mappedWhenManaged | XtCMappedWhenManaged | Boolean | True
    XtNscreen | XtCScreen | Screen * | NULL

  Translations
The toggle action toggles the widget between `on' and `off'. By default it is bound to a click of the left mouse button as well as to the Return key.

<Btn1Down>: set_shadow(sunken)
<Btn1Up>: toggle() set_shadow()
<Key>Return: toggle()

  Actions

toggle
    The toggle action switches the state. Depending on the resources it might change the tickmark. The onCallback or offCallback functions are called, with the event as call_data argument.
    void toggle($, XEvent* event, String* params, Cardinal* num_params)
    {
        XtVaSetValues($, "on", !$on, NULL);
        XtCallCallbackList($, $on ? $onCallback : $offCallback, event);
    }

switch_on
    The switch_on action switches the button to `on' if it is `off', otherwise it does nothing. By default it isn't bound to any event. If the widget is changed, the onCallback is called with the event as call_data.
    void switch_on($, XEvent* event, String* params, Cardinal* num_params)
    {
        if (! $on) {
            XtVaSetValues($, "on", True, NULL);
            XtCallCallbackList($, $onCallback, event);
        }
    }

switch_off
    The switch_off action switches the widget to `off' if the state is `on', otherwise it does nothing. When the widget changes states, the offCallback is called, with a pointer to the XEvent structure as call_data argument.
    void switch_off($, XEvent* event, String* params, Cardinal* num_params)
    {
        if ($on) {
            XtVaSetValues($, "on", False, NULL);
            XtCallCallbackList($, $offCallback, event);
        }
    }

Importss
The Converters file is needed for the Icon type.
incl
 <Xfwf/Converters.h>

  Private variables
The on_gc GC holds the picture of the tick mark for the `on' state.

GC  on_gc
The off_gc holds the picture for the `off' state.

GC  off_gc
The previous value of leftMargin is stored in a private variable. This value is added to the width of the widest pixmap to give the new value of leftMargin.

Dimension  saveLeftMargin

  Methods
The GC's are created for the first time and the left margin is increased to make room for the on and off icons.
initialize(Widget  request, $, ArgList  args, Cardinal * num_args)
{
    int status;
    Dimension w1, w2, w;
    $on_gc = NULL;
    $off_gc = NULL;
    create_on_gc($);
    create_off_gc($);
    w1 = $onIcon ? $onIcon->attributes.width : 0;
    w2 = $offIcon ? $offIcon->attributes.width : 0;
    w = max(w1, w2);
    if (w != 0) XtVaSetValues($, XtNleftMargin, $leftMargin + w, NULL);
}
Question: Does the computation of leftMargin have the desired effect? Since set_values is downward chained, the Label widget has already processed it; changing leftMargin doesn't cause Label to recompute the preferred sizeots
Boolean  set_values(Widget  old, Widget  request, $, ArgList  args, Cardinal * num_args)
{
    Boolean redraw = False, compute_margin = False;
    Dimension w1, w2, w;
    if ($onIcon != $old$onIcon) {
	create_on_gc($);
	compute_margin = True;
    }
    if ($offIcon != $old$offIcon) {
	create_off_gc($);
	compute_margin = True;
    }
    if ($on != $old$on) {
        redraw = True;
    }
    if (compute_margin) {
	/* Compute w = old margin between icons and text */
	w1 = $old$onIcon ? $old$onIcon->attributes.width : 0;
	w2 = $old$offIcon ? $old$offIcon->attributes.width : 0;
	w = $old$leftMargin - max(w1, w2);
	/* Compute new left margin w = w + width of icons */
	w1 = $onIcon ? $onIcon->attributes.width : 0;
	w2 = $offIcon ? $offIcon->attributes.width : 0;
	w = w + max(w1, w2);
	if ($old$leftMargin != w) {
	    XtVaSetValues($, XtNleftMargin, w, NULL);
	    redraw = False;
	} else
	    redraw = True;
    }
    return redraw;
}
The expose method uses the expose method of the superclass to draw the button and then possibly adds a tick mark.
expose($, XEvent * event, Region  region)
{
    Position x, y;
    Dimension w, h;
    if (! XtIsRealized($)) return;
    #expose($, event, region);
    $compute_inside($, x, y, w, h);
    if ($on  $onIcon) {
	y = y + (h - $onIcon->attributes.height)/2;
	XSetTSOrigin(XtDisplay($), $on_gc, x, y);
	XSetClipOrigin(XtDisplay($), $on_gc, x, y);
	XFillRectangle(XtDisplay($), XtWindow($), $on_gc, x, y,
		       $onIcon->attributes.width,
		       $onIcon->attributes.height);
    } else if ($offIcon) {
	y = y + (h - $offIcon->attributes.height)/2;
	XSetTSOrigin(XtDisplay($), $off_gc, x, y);
	XSetClipOrigin(XtDisplay($), $off_gc, x, y);
	XFillRectangle(XtDisplay($), XtWindow($), $off_gc, x, y,
		       $offIcon->attributes.width,
		       $offIcon->attributes.height);
    }
}

Utilities
The create_on_gc function creates a GC with the onIcon as tile.
create_on_gc($)
{
    XtGCMask mask = GCFillStyle;
    XGCValues values;
    if ($on_gc != NULL) XtReleaseGC($, $on_gc);
    if ($onIcon  $onIcon->pixmap != None) {
	values.tile = $onIcon->pixmap;
	mask |= GCTile;
    }
    if ($onIcon  $onIcon->mask != None) {
	values.clip_mask = $onIcon->mask;
	mask |= GCClipMask;
    }
    values.fill_style = FillTiled;
    $on_gc = XtGetGC($, mask, values);
}
The create_off_gc function creates a GC with the offIcon as tile.
create_off_gc($)
{
    XtGCMask mask = GCFillStyle;
    XGCValues values;
    if ($off_gc != NULL) XtReleaseGC($, $off_gc);
    if ($offIcon  $offIcon->pixmap != None) {
	values.tile = $offIcon->pixmap;
	mask |= GCTile;
    }
    if ($offIcon  $offIcon->mask != None) {
	values.clip_mask = $offIcon->mask;
	mask |= GCClipMask;
    }
    values.fill_style = FillTiled;
    $off_gc = XtGetGC($, mask, values);
}