set_values()set_values()Nameset_values - Object class method for handling resource changes.
Synopsis
typedef Boolean (*XtSetValuesFunc)(Widget, Widget, Widget, ArgList,
Cardinal *);
Widget current;
Widget request;
Widget set;
ArgList args;
Cardinal *num_args;
Inputs
current Specifies a copy of the widget made by XtSetValues() before
any resources are changed or any set_values() methods are
called.
request Specifies a copy of the widget made by XtSetValues() after
the resources are changed as requested, but before any
set_values() methods are called.
set Specifies the actual widget with resources set and as modi‐
fied by any superclass methods that have been called by
XtSetValues().
args Specifies the argument list passed to XtSetValues().
num_args Specifies the number of arguments in the args.
Returns
True if the resource changes require the widget to be redrawn; False
otherwise.
Description
The set_values() method is registered on the set_values field of the
Object, RectObj, or Core class part structure. It is called by XtSet‐
Values() to do any processing necessary when the values of widget
resources are changed. This method is chained in superclass-to-
subclass order.
The set argument is the widget that has had its resources set, and has
been passed to the superclass set_values() methods. Any changes to
resource or non-resource fields should be made to this widget.
The current argument is a copy of the widget that was made by XtSetVal‐
ues() before any of the resource values were changed as requested in
the argument list. The set_values() method can compare the resource
fields of set and current to determine which resources have been
changed.
The request argument is a copy of the widget made after the resource
values were set, but before XtSetValues() called any set_values() meth‐
ods. A set_values() method can compare fields in request, set, and
current to determine whether a field was set from the argument list
(i.e., at the request of the programmer) or whether it was modified by
a superclass set_values() method. A set_values() method may override
values set by a superclass, but shouldn't change values that are
explicitly requested in a call to XtSetValues(). See the "Background"
section below for more information.
The args and num_args arguments are the argument list that was passed
to XtSetValues() (or the variable-length argument list passed to
XtVaSetValues() transformed into an ArgList). They can be used to set
subpart resources with XtSetSubvalues(), to set values on privately
created children widgets, or to set any other resources that do not
appear on the resource list of the widget class. The args and num_args
arguments were added to this method in Release 4. Prior to Release 4,
subpart and other resources had to be set in the set_values_hook()
method, which is now obsolete.
The set_values() method returns True if the widget needs to be redrawn
in response to the resources changes, and False otherwise. It should
not do any redisplay itself; if any of the set_values() methods returns
True, XtSetValues() will generate an Expose event for the window by
calling XClearArea(), and the widget's expose() method will be called.
A programmer may call XtSetValues() to set a widget's geometry fields
directly. A set_values() method may also set these fields in response
to other resource changes (if a label widget's label changes, for exam‐
ple, it may change its width). Note that this is one of the few times
that a widget is allowed to directly set its own geometry fields. The
other times are in the initialize() and (obsolete) initialize_hook()
methods, and the (also obsolete) set_values_hook() method. A
set_value() method may directly set its geometry fields, but should not
do any processing based on those new values; the widget's parent must
approve them first. If any of a widget's geometry fields have changed
after all the set_values() methods have been called, XtSetValues() will
call XtMakeGeometryRequest() to actually request the geometry change
from the widget's parent. If the request is denied, XtSetValues() will
reset the geometry fields to their original values. If the request is
successful and the widget's size has changed, it will invoke the wid‐
get's resize() method. Most widgets will receive an Expose event after
they are resized, and so a change to geometry fields alone is not rea‐
son enough for set_values() to return True.
The set_values() method must not assume that the widget is realized.
The set_values() method is chained in superclass-to-subclass order and
cannot be inherited. If a widget has no resources, or needs to do no
recalculation when those resources change, it does not need a set_val‐
ues() method and can specify NULL for the set_values field of the class
part structure.
See XtSetValues(1) for full details on the resource-setting process.
See Constraint set_values(4) for information about handling changes to
Constraint resources. See the "Background" section below for informa‐
tion about overriding values set by a superclass.
Usage
A typical set_values() method will compare the fields of set and cur‐
rent for most resources defined by the class. If a resource value has
changed, it will take whatever actions are appropriate. Some common
tasks of the set_values() method are:
· Copies resources that are passed by reference. If a resource that
was copied in the initialize() method has changed, the old value
must be freed, and the new value copied. String resources are typi‐
cally copied by a widget so that the programmer may modify or free
them after setting them in the widget. If this freeing and copying
are done in separate procedures, the procedure to free the value can
usually be shared with the destroy() method and the procedure to
copy the value can usually be shared with the initialize() method.
· Recomputes derived fields when the resources they are derived from
have changed. If the XtNforeground or XtNfont resource of a widget
has changed, for example, it will probably have to free its current
shared GC and allocate a new one. Note that resources may be
derived from other resources. If a widget's width can be specified
through either the XtNwidth or the XtNcolumns resource, then a
change to either of these resources should cause a change to the
other (and if both are changed, one should take clearly defined and
documented precedence). If the code to calculate the values of
derived fields is placed in separate procedures (code to allocate
GCs, for example) those procedures can usually be shared with the
initialize() method.
· Checks modified resources for consistency and reasonableness. If
inconsistent or unreasonable resources are found, their values
should be set to something valid, and a warning message should be
issued.
· Restores the value of resource that are not allowed to be changed.
Some widgets do not allow changes to some of their resources. If
these values are changed in the set_values() method, they should be
reset (i.e., the set field restored from the current field) and a
warning message should be issued.
· Overrides derived fields calculated by superclasses, if necessary.
If the XtNcolumns resource of a widget has changed, for example, a
superclass may have one way of deriving XtNwidth from it, and a
subclass may have a different way (the subclass may have different
margins, for example). See the "Background" section below, for fur‐
ther discussion about overriding values set by a superclass.
· Uses args and num_args to set the value of resources that do not
appear in the class resource list. These may be subpart resources
(set with XtSetSubvalues()) or resources of children objects or wid‐
gets (set with XtSetValues()) which the widget wants to export as
its own. (See get_values_hook(4) for a discussion and examples of
widgets that export resources of child widgets or subparts.)
· Checks for changes to the sensitivity state of the widget. XtSet‐
Sensitive() uses XtSetValues() to set the sensitive and ances‐
tor_sensitive fields of a widget. A widget class that displays
itself differently when insensitive should check for sensitivity
changes in its set_values() method. See XtSetSensitive(1) for more
information on widget sensitivity.
· Keeps track of whether the widget needs to be redrawn. A common
technique in set_values() methods is to initialize a needs_redraw
variable to False, and then set it to True if any resources are
changed that would require the widget to be redrawn. This value
then becomes the return value of the method. A widget will commonly
need to be redrawn if colors, fonts, or other GC components have
changed; if its sensitivity state has changed; or if a resource that
specifies data to be displayed (the XtNlabel resource of the Label
widget, for example) has changed.
Example
The following procedure is the set_values() method, slightly edited,
from the Xaw List widget. Note that it frees and reallocates its GCs
if the foreground, background, or font have changed. If any of a large
number of resources have changed that would affect the layout or size
of the list, it calls an internal procedure that will calculate inter‐
nal layout information and set new values for the widget's geometry
fields. Finally, it checks whether it has been made insensitive and if
so, turns off its highlighting.
Note that this procedure (and most existing set_values() methods) names
the set argument new. "new" is a reserved word in C++, and your code
will be more portable if you avoid using it in C.
/* ARGSUSED */
static Boolean SetValues(current, request, new, args, num_args)
Widget current, request, new;
ArgList args;
Cardinal *num_args;
{
ListWidget cl = (ListWidget) current;
ListWidget rl = (ListWidget) request;
ListWidget nl = (ListWidget) new;
Boolean redraw = FALSE;
if ((cl->list.foreground != rl->list.foreground)
(cl->core.background_pixel != rl->core.background_pixel)
(cl->list.font != rl->list.font) ) {
XGCValues values;
XGetGCValues(XtDisplay(current), cl->list.graygc, GCTile, &values);
XmuReleaseStippledPixmap(XtScreen(current), values.tile);
XtReleaseGC(current, cl->list.graygc);
XtReleaseGC(current, cl->list.revgc);
XtReleaseGC(current, cl->list.normgc);
GetGCs(new);
redraw = TRUE;
}
/* Reset row height. */
if ((cl->list.row_space != rl->list.row_space)
(cl->list.font != rl->list.font))
nl->list.row_height = nl->list.font->max_bounds.ascent
+ nl->list.font->max_bounds.descent
+ nl->list.row_space;
if ((cl->core.width != rl->core.width)
(cl->core.height != rl->core.height)
(cl->list.internal_width != rl->list.internal_width)
(cl->list.internal_height != rl->list.internal_height)
(cl->list.column_space != rl->list.column_space)
(cl->list.row_space != rl->list.row_space)
(cl->list.default_cols != rl->list.default_cols)
( (cl->list.force_cols != rl->list.force_cols) &&
(rl->list.force_cols != rl->list.ncols) )
(cl->list.vertical_cols != rl->list.vertical_cols)
(cl->list.longest != rl->list.longest)
(cl->list.nitems != rl->list.nitems)
(cl->list.font != rl->list.font)
(cl->list.list != rl->list.list) ) {
ResetList(new, TRUE, TRUE);
redraw = TRUE;
}
if (cl->list.list != rl->list.list)
nl->list.is_highlighted = nl->list.highlight = NO_HIGHLIGHT;
if ((cl->core.sensitive != rl->core.sensitive)
(cl->core.ancestor_sensitive != rl->core.ancestor_sensitive)) {
nl->list.highlight = NO_HIGHLIGHT;
redraw = TRUE;
}
if (!XtIsRealized(current))
return(FALSE);
return(redraw);
}
Background
Like the initialize() method, set_values() mostly deals only with the
fields defined in the subclass, but it has to resolve conflicts with
its superclass, especially conflicts over width and height.
Sometimes a subclass may want to overwrite values filled in by its
superclass. In particular, size calculations of a superclass are often
incorrect for a subclass and, in this case, the subclass must modify or
recalculate fields declared and computed by its superclass.
As an example, a subclass can visually surround its superclass display.
In this case, the width and height calculated by the superclass
set_values() method are too small and need to be incremented by the
size of the surround. The subclass needs to know if its superclass's
size was calculated by the superclass or was specified explicitly. All
widgets must place themselves into whatever size is explicitly given,
but they should compute a reasonable size if no size is requested. How
does a subclass know the difference between a specified size and a size
computed by a superclass?
The request and set parameters provide the necessary information. The
request widget is a copy of the widget, updated as originally
requested. The set widget starts with the values in the request, but
it has additionally been updated by all superclass set_values() methods
called so far. A subclass set_values() method can compare these two to
resolve any potential conflicts. The set_values() method need not
refer to the request widget unless it must resolve conflicts between
the current and set widgets. Any changes the widget needs to make,
including geometry changes, should be made in the set widget.
In the above example, the subclass with the visual surround can see if
the width and height in the request widget differ from the width and
height in the set widget. If so, it means that a superclass has modi‐
fied these fields (which means that the programmer did not request them
specifically) and the subclass can add its surround size to the width
and height fields in the set widget. If the fields are the same, the
subclass must make do with the specified size.
There is a twist, however, on this problem of not overriding resources
explicitly requested by the user. If the programmer sets a new label
on a Label widget, for example, the widget is allowed to change its
size as needed to accommodate the label. If the programmer sets a new
label and a new width at the same time, however, the new width should
take precedence, regardless of the size of the label. The difficulty
arises in the case that the programmer requests a particular width
which happens to be the current width. He is expecting to get exactly
that width, but the set_values() method may not detect that that
resource has changed, and will resize the widget as required for the
new label. The only general way out of this situation is to check each
element of args to see if the any of the resources that are being set
are named XtNwidth.
See AlsoXtSetValues(1),
Core(3),
Constraint set_values(4), set_values_almost(4), set_values_hook(4).
Xt - Intrinsics Methods set_values()