(3)

NAME
XfwfRadioGroup

DESCRIPTION
The RadioGroup widget is a simple specialization of the Group widget. It has an extra resource, labels, which holds the labels of the toggle buttons that are created automatically. For the common case that a Group widget contains only radio buttons, the RadioGroup widget is much more convenient. It is also much less flexible. E.g., it is very difficult to change resources of the radio buttons, when the defaults are not satisfactory. In particular, the Toggle widgets are created with the following hardcoded resources: shrinkToFit = True, border_width = 0, frameWidth = 0. The names of the Toggle widgets are equal to their labels.

  Public variables
XfwfRadioGroup
Name | Class | Type | Default
XtNlabels | XtCLabels | StringArray | NULL

XtNlabels
    The labels resource is an array of strings. Each string will become the label of a toggle button. The last member of the array must be a NULL pointer. There is a converter that allows the list of strings to be entered as a single string, with any character as separator.

    StringArray  labels = NULL
    XfwfGroup
    Name | Class | Type | Default
    XtNlabel | XtCLabel | String | NULL
    XtNfont | XtCFont | FontStruct | XtDefaultFont
    XtNforeground | XtCForeground | Pixel | XtDefaultForeground
    XtNselectionStyle | XtCSelectionStyle | SelectionType | XfwfSingleSelection
    XtNselection | XtCSelection | Long | 0
    XtNactivate | XtCActivate | Callback | NULL
    XfwfRowCol
    Name | Class | Type | Default
    XtNstoreByRow | XtCStoreByRow | Boolean | True
    XtNrows | XtCRows | Int | 0
    XtNcolumns | XtCColumns | Int | 0
    XtNalignment | XtCAlignment | Alignment | XfwfTopLeft
    XtNshrinkToFit | XtCShrinkToFit | Boolean | False
    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

  Exports
The type StringArray represents an array of Strings, with the proviso that by convention the last member of a StringArray is always a NULL pointer. There is a converter that can construct a StringArray from a single string.

type
 StringArray = String *

Importss
incl
 <Xfwf/Toggle.h>

  Methods
class_initialize registers the type converter.
class_initialize()
{
    XtSetTypeConverter(XtRString, "StringArray", cvtStringToStringArray,
		       NULL, 0, XtCacheNone, NULL);
}
In the initialize method, the utility function create_toggles is called, which creates toggle widgets for each label in the labels resource.
initialize(Widget  request, $, ArgList  args, Cardinal * num_args)
{
    $labels = newStringArray($labels);
    create_toggles($);
}
The set_values method makes a private copy of the labels resource and calls create_labels. Since the RadioGroup doesn't draw anything itself, the return value is always False.
Boolean  set_values(Widget  old, Widget  request, $, ArgList  args, Cardinal * num_args)
{
    if ($old$labels != $labels) {
	freeStringArray($old$labels);
	$labels = newStringArray($labels);
	create_toggles($);
    }
    return False;
}

Utilities
The function create_toggles first destroys all existing children and then creates new ones. For each string in the labels resource there will be an XfwfToggle button.
create_toggles($)
{
    Cardinal i;
    StringArray s;
    for (i = 0; i < $num_children; i++)
	XtDestroyWidget($children[i]);
    if ($labels == NULL) return;
    for (s = $labels, i = 0; s[i] != NULL; i++) {
	(void) XtVaCreateManagedWidget
	    (s[i], xfwfToggleWidgetClass, $, XtNlabel, s[i], XtNshrinkToFit,
	     True, XtNborderWidth, 0, XtNframeWidth, 0, NULL);
    }
}
The converter from String to StringArray makes a copy of the passed string and then replaces all occurences of the delimiter with a nul byte. The StringArray a is filled with pointers to the parts of the string. The delimiter character is the first character in the string. def done(type, value) = do {
    if (to->addr != NULL) {
        if (to->size < sizeof(type)) {
            to->size = sizeof(type);
            return False;
        }
        *(type*)(to->addr) = (value);
        } else {
        static type static_val;
        static_val = (value);
        to->addr = (XtPointer)static_val;
        }
        to->size = sizeof(type);
        return True;
    }while (0 )
Boolean  cvtStringToStringArray(Display * display, XrmValuePtr  args, Cardinal * num_args, XrmValuePtr  from, XrmValuePtr  to, XtPointer * converter_data)
{
    String t, s;
    StringArray a = NULL;
    Cardinal i;
    char delim;
    if (*num_args != 0)
	XtAppErrorMsg(XtDisplayToApplicationContext(display),
		      "cvtStringToStringArray", "wrongParameters",
		      "XtToolkitError",
		      "String to StringArray conversion needs no arguments",
		      (String*) NULL, (Cardinal*) NULL);
    delim = ((String) from->addr)[0];
    s = XtNewString((String) from->addr + 1);
    i = 0;
    while (s  *s) {
	t = strchr(s, delim);
        if (t) *t = '\0';
	a = (StringArray) XtRealloc((String) a, (i + 1) * sizeof(*a));
	a[i] = s;
	i++;
        s = t ? t + 1 : NULL;
    }
    a = (StringArray) XtRealloc((String) a, (i + 1) * sizeof(*a));
    a[i] = NULL;
    done(StringArray, a);
}
The function newStringArray makes a copy of a StringArray. It allocates new space for the array itself and for the strings that it contains.
StringArray  newStringArray(StringArray  a)
{
    Cardinal n, i;
    StringArray s;
    if (!a) return NULL;
    for (s = a, n = 0; s[n]; n++) ;
    s = (StringArray) XtMalloc((n + 1) * sizeof(*s));
    for (i = 0; i < n; i++) s[i] = XtNewString(a[i]);
    s[n] = NULL;
    return s;
}
freeStringArray deallocates the array and all strings it contains.
freeStringArray(StringArray  a)
{
    Cardinal i;
    if (!a) return;
    for (i = 0; a[i]; i++) XtFree(a[i]);
    XtFree((String) a);
}