Widget resources and functions
Widgets are configured and controlled by the application through resources and functions. Widget resources define the behavior and appearance of a widget. Widget functions are messages that can be sent to a widget to tell it to do something.
In VA Smalltalk, resource accessors and functions are implemented as Smalltalk methods in widget classes. Widget resource methods provide access to a widget's resources. All methods that are not resource methods are widget function methods. A method's comments and its message specification indicate whether it is a resource method or a function method.
Resources are somewhat analogous to Smalltalk instance variables, and resource set and get methods are similar to instance variable accessor methods. However, there are several important differences:
Resources might or might not be implemented using instance variables, and the implementation varies from platform to platform.
Changes to values in widget resources are immediately reflected in the appearance of the widget.
On platforms running Motif as the native widget system, VA Smalltalk widget resource values can be set using standard X resource files, like any other Motif application.
All widgets have a core set of resources. For example, all widgets have width and height resources. A widget can also have resources specific to its behavior. For example, the items resource of the CwList widget defines what items are displayed in the widget. Default values are provided for all of a widget's resources.
Resources defined by a widget's superclasses are inherited. For example, consider the widget class CwPushButton. This class is a subclass of CwLabel, CwPrimitive, CwBasicWidget, and CwWidget. CwPushButton inherits resources from all of its superclasses, and defines additional resources of its own. The default value of an inherited resource can be overridden.
The following table illustrates the resources that are available for a CwPushButton widget. Many of the resources are provided by CwWidget, and these are available to all widgets.
Table 31. Widget resources for the CwPushButton class
(plus 16 attachment- related resources)
Appendix A, "Widget resources and callbacks" provides a table for each class in the CwWidget hierarchy.
A widget's resources are set or retrieved using the set and get accessor methods of the widget, which are the names that correspond directly to the associated resource name. Resource setting methods have a special property that can be sent to a widget to set initial state during widget creation, from inside a create argBlock.
Not all widget resources can be modified or retrieved at any time. Widget resources have a resource access designator that indicates when the resource can be set or retrieved. Resources are tagged with the letters C, S, or G to indicate when the resource can be modified or retrieved, as follows:
The application can set the resource at creation time only (C).
The application can set the resource at any time (S).
The application can retrieve, or get, the resource at any time after the widget is created (G).
Resources are manipulated using get and set accessor methods derived from the OSF/Motif name for the resource by removing the 'XmN' prefix. For example, the Motif resource XmNheight for a widget is retrieved and modified using the height and height: methods, respectively. The specification for each resource method provides the resource access designation information (C, S, G).
Create-only (C) resources can only be set using an argBlock at widget creation time. An argBlock is a single argument Smalltalk block of code that is evaluated with the widget being created as its argument. Resources with an (S) designation can also be set in the argBlock. The argBlock is evaluated before the widget is fully created, that is, while it is still under construction, but after a Smalltalk object has been created to represent the widget. If argBlock is not required, nil can be used for the argBlock argument, rather than unnecessarily creating an empty block.
Always set resources in the create argBlock wherever possible. Also, unless names are needed for X resource files, use the widget's name to establish a default resource value as described in the widget creation section on page 1. Creating a widget. If the system has more information available at the time of widget creation, it can perform more optimization. On some platforms a significant performance advantage is achieved by setting resources in the create argBlock rather than immediately after creation, which might cause default widget configuration to have to be "undone".
In the following example, the width and height resources for a drawing area are explicitly set in an argBlock when the drawing area widget is created. These specify the size in pixels of the drawing area widget. The size of the shell widget is calculated based on the size of the drawing area widget. In general, when the size of a widget is not explicitly specified, it is calculated based on the size of its children, recursively. The string arguments in the creation messages specify the names of the widgets. By default, the name of the top-level shell appears as the window title.
| shell drawingArea |
shell := CwTopLevelShell
createApplicationShell: 'ShellName'
argBlock: nil.
drawingArea := shell
createDrawingArea: 'draw'
argBlock: [:w | w width: 100; height: 100].
drawingArea manageChild.
shell realizeWidget
Resources with set (S) and get (G) designations can be set and retrieved, respectively, after widget creation using the appropriate set and get methods.
Multiple resources with set (S) designation can also be set simultaneously after the widget is created using the setValuesBlock: message, which takes an argBlock as argument. The setValuesBlock: method is the recommended way of setting multiple resources for a widget after the widget is created. Normally, after a widget has been created and a resource is modified, which changes a widget's appearance, the widget is redisplayed to show the change. Using a setValuesBlock is more efficient than setting the resources outside the block because the widget can then optimize updates together, even if several of them change the widget's appearance. The block passed to setValuesBlock: has the same format as the argBlock used when creating a widget.
In the following example, the geometry of a shell widget is changed. Assume that the variable shell is a top-level shell that has been created and realized.
"Set widget geometry using a series of set accessor methods.
The shell is redrawn up to four times, after for each resource change."
x: 10;
y: 10;
width: 100;
height: 100.
"Set widget geometry using a set values block.
The shell is redrawn only after, with the final dimensions,
at the final position."
setValuesBlock: [:w |
x: 10;
y: 10;
width: 100;
height: 100].
Some resources change their values when the value of a different resource in the same widget is changed. To avoid this "push-down-here-pop-up-there" effect, such resources must be set simultaneously using an argBlock, either on creation or after creation using setValuesBlock:.This situation occurs with left/right and top/bottom CwForm attachment resources, which should always be set in pairs.
Function methods
Widget methods that are not resource set or get methods are widget function methods. Unlike resource setting messages, function messages can only be sent to widgets after they have been created. While resource methods are used to access or change widget state, function methods typically perform more complex operations, and in some cases modify resource values. While resource get and set methods uniformly require zero arguments and one argument respectively, widget function methods take varying numbers of arguments, depending on the particular function. The manageChild method is an example of a widget function.
Functions often alter the resource values of a widget as a side effect. For example, the setString: function for text widgets alters the value resource of the widget. In some cases it is possible to achieve the same effect using either a resource method or a function method.
Do not call function methods from inside a create argBlock. Because the widget is not fully created when the create argBlock is evaluated, invoking widget functions results in errors.
Last modified date: 05/13/2020