Writing an extended widget
The first step in writing an extended widget is to create a subclass of the appropriate extended widget framework class. Extended widgets that are not intended to contain child widgets should be implemented as subclasses of CwExtendedPrimitive. Those that are intended to contain child widgets should be implemented as subclasses of CwExtendedComposite. It is important to understand this difference:
• A subclass of CwExtendedPrimitive can be implemented using a primary widget with child widgets, however an application programmer making use of this type of extended widget can not add any children to it.
• A subclass of CwExtendedComposite can be implemented using just a single widget, say for example a CwForm with no children, but the same application programmer can create this type of extended widget and add as many children as are permitted by the extended widget's API.
After the subclass has been created, it should define an instance variable for each resource and callback provided by the extended widget, as well as instance variables required for any other aspects of the widget's implementation.
Defining the extended widget class
An extended widget is implemented using a widget tree consisting of other basic or extended widgets. This tree is called the primary widget tree. The root of the primary widget tree is known as the primary widget. The extended widget class must override the createPrimaryWidget:parent:argBlock: method. This method creates and answers the primary widget, but does not create the children of the primary widget. If the primary widget tree consists of more than one widget, the extended widget class must override createWidgetSystem. This method creates the remainder of the primary widget tree, that is, the children of self primaryWidget.
Initialization
Three methods can be overridden to initialize the state of the widget. The initialize method is run as the first step in extended widget creation. It is useful for initializing the internal state of the widget, except for resources. The initializeResources method initializes the instance variables representing resources. Both of these methods are run before the primary widget tree has been created. The initializeAfterCreate method is run after the primary widget tree has been created. It is useful for configuring widgets after they have been created, and for initializing graphics resources.
Resources
Set and get accessor methods should be added for each resource provided by the extended widget. Usually, the get method simply answers the corresponding instance variable. The set method usually sets the corresponding instance variable and makes any required changes in the primary widget tree.
Callbacks
Set and get accessor methods must be added for each callback provided by the extended widget. The set accessor method simply sets the instance variable used to store an ordered collection of CwCallbackRec objects for the particular callback. It is typically only called by the get method to initialize the ordered collection. The valueChangedCallback: method in the example that follows is a callback set accessor.
The get accessor method for a callback is a little more involved. In order to work properly with methods inherited from CwExtendedWidget, the constant used to specify the type of the callback--for example, XmNactivateCallback for an activate callback--is a pool variable that must be equal to the get method's selector--for example, activateCallback. The valueChangedCallback method in the example is a callback get accessor. Callback type specifiers are already defined in the CwConstants pool dictionary, however, if a new name is desired, it can be added to an application-specific pool dictionary using the same naming convention.
The get accessor must answer an ordered collection, to which callback descriptors are added whenever a callback is registered. If the callback resource is uninitialized, the get method must set the callback resource to a new OrderedCollection, and answer that.
Registered callbacks can be run by the extended widget using the callCallbacks:callData: method. The example extended widget calls its valueChanged callback in the valueChangedCallback: method.
Widget-specific methods
An extended widget works by forwarding most widget messages to its primary widget. All of the methods inherited from CwWidget are automatically forwarded to the primary widget if they are not explicitly overridden. In simple cases, an extended widget's behavior can be implemented simply by adding resource and callback methods as described above. For more complicated widgets, it is usually necessary to extend the basic widget protocol by providing methods to support the new operations on the extended widget.
Using an extended widget
After an extended widget class has been defined, application developers can create instances of the extended widget by sending the createWidget:parent:argBlock: or createManagedWidget:parent:argBlock: method to the extended widget's class. The create argBlock should only set resources that are defined for the extended widget or in CwWidget, and should not assume a particular underlying implementation.
Last modified date: 01/29/2015