home *** CD-ROM | disk | FTP | other *** search
- .\" $XConsortium: CH03,v 1.8 91/08/27 10:00:40 swick Exp $
- .\"
- .\" Copyright 1985, 1986, 1987, 1988, 1991
- .\" Massachusetts Institute of Technology, Cambridge, Massachusetts,
- .\" and Digital Equipment Corporation, Maynard, Massachusetts.
- .\"
- .\" Permission to use, copy, modify and distribute this documentation for any
- .\" purpose and without fee is hereby granted, provided that the above copyright
- .\" notice appears in all copies and that both that copyright notice and this
- .\" permission notice appear in supporting documentation, and that the name of
- .\" M.I.T. or Digital not be used in in advertising or publicity pertaining
- .\" to distribution of the software without specific, written prior permission.
- .\" M.I.T and Digital makes no representations about the suitability of the
- .\" software described herein for any purpose.
- .\" It is provided ``as is'' without express or implied warranty.
- \&
- .sp 1
- .ce 3
- \s+1\fBChapter 3\fP\s-1
-
- \s+1\fBComposite Widgets and Their Children\fP\s-1
- .sp 2
- .nr H1 3
- .nr H2 0
- .nr H3 0
- .nr H4 0
- .nr H5 0
- .LP
- .XS
- Chapter 3 \- Composite Widgets and Their Children
- .XE
- .IN "Composite widgets"
- Composite widgets (widgets whose class is a subclass of
- .PN compositeWidgetClass )
- can have an arbitrary number of children.
- Consequently, they are responsible for much more than primitive widgets.
- Their responsibilities (either implemented directly by the widget class
- or indirectly by \*(xI functions) include
- .IP \(bu 5
- Overall management of children from creation to destruction.
- .IP \(bu 5
- Destruction of descendants when the composite widget is destroyed.
- .IP \(bu 5
- Physical arrangement (geometry management) of a displayable subset of
- children (that is, the managed children).
- .IP \(bu 5
- Mapping and unmapping of a subset of the managed children.
- .LP
- Overall management is handled by the generic procedures
- .PN XtCreateWidget
- and
- .PN XtDestroyWidget .
- .PN XtCreateWidget
- adds children to their parent by calling the parent's insert_child
- procedure.
- .PN XtDestroyWidget
- removes children from their parent by calling the parent's delete_child
- procedure and ensures that all children of a destroyed composite widget
- also get destroyed.
- .LP
- Only a subset of the total number of children is actually managed by
- the geometry manager and hence possibly visible.
- For example, a composite editor widget
- supporting multiple editing buffers might allocate one child
- widget for each file buffer,
- but it might only display a small number of the existing buffers.
- Widgets that are in this displayable subset are called managed widgets
- and enter into geometry manager calculations.
- The other children are called unmanaged widgets
- and, by definition, are not mapped by the \*(xI.
- .LP
- Children are added to and removed from their parent's managed set by using
- .PN XtManageChild ,
- .PN XtManageChildren ,
- .PN XtUnmanageChild ,
- and
- .PN XtUnmanageChildren ,
- which notify the parent to recalculate the physical layout of its children
- by calling the parent's change_managed procedure.
- The
- .PN XtCreateManagedWidget
- convenience function calls
- .PN XtCreateWidget
- and
- .PN XtManageChild
- on the result.
- .LP
- Most managed children are mapped,
- but some widgets can be in a state where they take up physical space
- but do not show anything.
- Managed widgets are not mapped automatically
- if their \fImap_when_managed\fP field is
- .PN False .
- The default is
- .PN True
- and is changed by using
- .PN XtSetMappedWhenManaged .
- .LP
- Each composite widget class declares a geometry manager,
- which is responsible for figuring out where the managed children
- should appear within the composite widget's window.
- Geometry management techniques fall into four classes:
- .IP "Fixed boxes" 1.6i
- Fixed boxes have a fixed number of children created by the parent.
- All these children are managed,
- and none ever makes geometry manager requests.
- .IP "Homogeneous boxes" 1.6i
- Homogeneous boxes treat all children equally and apply the same geometry
- constraints to each child.
- Many clients insert and delete widgets freely.
- .IP "Heterogeneous boxes" 1.6i
- Heterogeneous boxes have a specific location where each child is placed.
- This location usually is not specified in pixels,
- because the window may be resized, but is expressed rather
- in terms of the relationship between a child
- and the parent or between the child and other specific children.
- The class of heterogeneous boxes is usually a subclass of
- Constraint .
- .IP "Shell boxes" 1.6i
- Shell boxes typically have only one child,
- and the child's size is usually
- exactly the size of the shell.
- The geometry manager must communicate with the window manager, if it exists,
- and the box must also accept
- .PN ConfigureNotify
- events when the window size is changed by the window manager.
-
- .NH 2
- Addition of Children to a Composite Widget: the insert_child Procedure
- .XS
- \*(SN Addition of Children to a Composite Widget: the insert_child Procedure
- .XE
- .LP
- .IN "insert_child procedure"
- To add a child to
- the parent's list of children, the
- .PN XtCreateWidget
- function calls the parent's class routine insert_child.
- The insert_child procedure pointer in a composite widget is of type
- .PN XtWidgetProc .
- .IN "insert_child procedure" "" "@DEF@"
- .FD 0
- typedef void (*XtWidgetProc)(Widget);
- .br
- Widget \fIw\fP;
- .FN
- .IP \fIw\fP 1i
- Passes the newly created child.
- .LP
- Most composite widgets inherit their superclass's operation.
- The insert_child routine in
- .PN CompositeWidgetClass calls the insert_position procedure
- and inserts the child at the specified position
- in the \fIchildren\fP list, expanding it if necessary.
- .LP
- Some composite widgets define their own insert_child routine
- so that they can order their children in some convenient way,
- create companion controller widgets for a new widget,
- or limit the number or class of their child widgets.
- A composite widget class that wishes
- to allow nonwidget children (see Chapter 12) must specify a
- .PN CompositeClassExtension
- extension record as described
- in section 1.4.2.1 and set the \fIaccepts_objects\fP field in this record to
- .PN True .
- If the
- .PN CompositeClassExtension
- record is not specified or the
- \fIaccepts_objects\fP field is
- .PN False ,
- the composite widget can assume that all its children are of a subclass of Core
- without an explicit subclass test in the insert_child procedure.
- .LP
- If there is not enough room to insert a new child in the \fIchildren\fP array
- (that is, \fInum_children\fP is equal to \fInum_slots\fP),
- the insert_child procedure must first reallocate the array
- and update \fInum_slots\fP.
- The insert_child procedure then places the child at the appropriate position
- in the array and increments the \fInum_children\fP field.
-
- .NH 2
- Insertion Order of Children: the insert_position Procedure
- .XS
- \fB\*(SN Insertion Order of Children: the insert_position Procedure\fP
- .XE
- .LP
- Instances of composite widgets sometimes need to specify more about the order in which
- their children are kept.
- For example,
- an application may want a set of command buttons in some logical order
- grouped by function,
- and it may want buttons that represent file names to be kept
- in alphabetical order without constraining the order in which the
- buttons are created.
- .LP
- An application controls the presentation order of a set of children by
- supplying an
- .IN XtNinsertPosition
- XtNinsertPosition
- resource.
- The insert_position procedure pointer in a composite widget instance is of type
- .PN XtOrderProc .
- .IN "XtOrderProc" "" "@DEF@"
- .FD 0
- typedef Cardinal (*XtOrderProc)(Widget);
- .br
- Widget \fIw\fP;
- .FN
- .IP \fIw\fP 1i
- Passes the newly created widget.
- .LP
- Composite widgets that allow clients to order their children (usually
- homogeneous boxes) can call their widget instance's insert_position
- procedure from the class's insert_child procedure to determine where a new
- child should go in its \fIchildren\fP array.
- Thus, a client using a composite class can apply different sorting criteria
- to widget instances of the class, passing in a different insert_position
- procedure resource when it creates each composite widget instance.
- .LP
- The return value of the insert_position procedure
- indicates how many children should go before the widget.
- Returning zero indicates that the widget should go before all other children,
- and returning \fInum_children\fP indicates that it should go after all other children.
- The default insert_position function returns \fInum_children\fP
- and can be overridden by a specific composite widget's resource list
- or by the argument list provided when the composite widget is created.
-
- .NH 2
- Deletion of Children: the delete_child Procedure
- .XS
- \*(SN Deletion of Children: the delete_child Procedure
- .XE
- .LP
- .IN "delete_child procedure"
- .LP
- To remove the child from the parent's \fIchildren\fP list, the
- .PN XtDestroyWidget
- function eventually causes a call to the Composite parent's class delete_child
- procedure.
- The delete_child procedure pointer is of type
- .PN XtWidgetProc .
- .FD 0
- typedef void (*XtWidgetProc)(Widget);
- .br
- Widget \fIw\fP;
- .FN
- .IP \fIw\fP
- Passes the child being deleted.
- .LP
- Most widgets inherit the delete_child procedure from their superclass.
- Composite widgets that create companion widgets define their own
- delete_child procedure to remove these companion widgets.
-
- .NH 2
- Adding and Removing Children from the Managed Set
- .XS
- \fB\*(SN Adding and Removing Children from the Managed Set\fP
- .XE
- .LP
- The \*(xI provide a set of generic routines to permit the addition of
- widgets to or the removal of widgets from a composite widget's managed set.
- .IN "change_managed procedure"
- These generic routines eventually call the composite widget's change_managed
- procedure if the procedure pointer is non-NULL.
- The change_managed procedure pointer is of type
- .PN XtWidgetProc .
- The widget argument specifies the composite widget whose managed child
- set has been modified.
-
- .NH 3
- Managing Children
- .XS
- \fB\*(SN Managing Children\fP
- .XE
- .LP
- To add a list of widgets to the geometry-managed (and hence displayable)
- subset of their Composite parent, use
- .PN XtManageChildren .
- .IN "XtManageChildren" "" "@DEF@"
- .FD 0
- typedef Widget *WidgetList;
- .sp
- void XtManageChildren(\fIchildren\fP, \fInum_children\fP)
- .br
- WidgetList \fIchildren\fP;
- .br
- Cardinal \fInum_children\fP;
- .FN
- .IP \fIchildren\fP 1i
- Specifies a list of child widgets. Each child must be of class
- RectObj or any subclass thereof.
- .IP \fInum_children\fP 1i
- Specifies the number of children in the list.
- .LP
- The
- .PN XtManageChildren
- function performs the following:
- .IP \(bu 5
- Issues an error if the children do not all have the same parent or
- if the parent's class is not a subclass of
- .PN compositeWidgetClass .
- .IP \(bu 5
- Returns immediately if the common parent is being destroyed;
- otherwise, for each unique child on the list,
- .PN XtManageChildren
- ignores the child if it already is managed or is being destroyed,
- and marks it if not.
- .IP \(bu 5
- If the parent is realized and after all children have been marked,
- it makes some of the newly managed children viewable:
- .RS
- .IP \- 5
- Calls the change_managed routine of the widgets' parent.
- .IP \- 5
- Calls
- .PN XtRealizeWidget
- on each previously unmanaged child that is unrealized.
- .IP \- 5
- Maps each previously unmanaged child that has \fImap_when_managed\fP
- .PN True .
- .RE
- .LP
- Managing children is independent of the ordering of children and
- independent of creating and deleting children.
- The layout routine of the parent
- should consider children whose \fImanaged\fP field is
- .PN True
- and should ignore all other children.
- Note that some composite widgets, especially fixed boxes, call
- .PN XtManageChild
- from their insert_child procedure.
- .LP
- If the parent widget is realized,
- its change_managed procedure is called to notify it
- that its set of managed children has changed.
- The parent can reposition and resize any of its children.
- It moves each child as needed by calling
- .PN XtMoveWidget ,
- which first updates the \fIx\fP and \fIy\fP fields and which then calls
- .PN XMoveWindow .
- .LP
- If the composite widget wishes to change the size or border width of any of
- its children, it calls
- .PN XtResizeWidget ,
- which first updates the
- \fIwidth\fP, \fIheight\fP, and \fIborder_width\fP
- fields and then calls
- .PN XConfigureWindow .
- Simultaneous repositioning and resizing may be done with
- .PN XtConfigureWidget ;
- see Section 6.6.
- .sp
- .LP
- To add a single child to its parent widget's set of managed children, use
- .PN XtManageChild .
- .IN "XtManageChild" "" "@DEF@"
- .FD 0
- void XtManageChild(\fIchild\fP)
- .br
- Widget \fIchild\fP;
- .FN
- .IP \fIchild\fP 1i
- Specifies the child. \*(rI
- .LP
- The
- .PN XtManageChild
- function constructs a
- .PN WidgetList
- of length 1 and calls
- .PN XtManageChildren .
- .sp
- .LP
- To create and manage a child widget in a single procedure, use
- .PN XtCreateManagedWidget
- or
- .PN XtVaCreateManagedWidget .
- .IN "XtCreateManagedWidget" "" "@DEF@"
- .FD 0
- Widget XtCreateManagedWidget(\fIname\fP, \fIwidget_class\fP, \fIparent\fP, \
- \fIargs\fP, \fInum_args\fP)
- .br
- String \fIname\fP;
- .br
- WidgetClass \fIwidget_class\fP;
- .br
- Widget \fIparent\fP;
- .br
- ArgList \fIargs\fP;
- .br
- Cardinal \fInum_args\fP;
- .FN
- .IP \fIname\fP 1i
- Specifies the resource instance name for the created widget.
- .IP \fIwidget_class\fP 1i
- Specifies the widget class pointer for the created widget. \*(rC
- .IP \fIparent\fP 1i
- Specifies the parent widget. Must be of class Composite or any
- subclass thereof.
- .IP \fIargs\fP 1i
- Specifies the argument list to override any other resource specifications.
- .IP \fInum_args\fP 1i
- Specifies the number of entries in the argument list.
- .LP
- The
- .PN XtCreateManagedWidget
- function is a convenience routine that calls
- .PN XtCreateWidget
- and
- .PN XtManageChild .
- .sp
- .LP
- .IN "XtVaCreateManagedWidget" "" "@DEF@"
- .FD 0
- Widget XtVaCreateManagedWidget(\fIname\fP, \fIwidget_class\fP, \fIparent\fP, ...)
- .br
- String \fIname\fP;
- .br
- WidgetClass \fIwidget_class\fP;
- .br
- Widget \fIparent\fP;
- .FN
- .IP \fIname\fP 1i
- Specifies the resource instance name for the created widget.
- .IP \fIwidget_class\fP 1i
- Specifies the widget class pointer for the created widget. \*(rC
- .IP \fIparent\fP 1i
- Specifies the parent widget. Must be of class Composite or any
- subclass thereof.
- .IP ... 1i
- Specifies the variable argument list to override any other
- resource specifications.
- .LP
- .PN XtVaCreateManagedWidget
- is identical in function to
- .PN XtCreateManagedWidget
- with the \fIargs\fP and \fInum_args\fP parameters replaced
- by a varargs list, as described in Section 2.5.1.
-
- .NH 3
- Unmanaging Children
- .XS
- \fB\*(SN Unmanaging Children\fP
- .XE
- .LP
- To remove a list of children from a parent widget's managed list, use
- .PN XtUnmanageChildren .
- .IN "XtUnmanageChildren" "" "@DEF@"
- .FD 0
- void XtUnmanageChildren(\fIchildren\fP, \fInum_children\fP)
- .br
- WidgetList \fIchildren\fP;
- .br
- Cardinal \fInum_children\fP;
- .FN
- .IP \fIchildren\fP 1i
- Specifies a list of child widgets. Each child must be of class
- RectObj or any subclass thereof.
- .IP \fInum_children\fP 1i
- Specifies the number of children.
- .LP
- The
- .PN XtUnmanageChildren
- function performs the following:
- .IP \(bu 5
- Issues an error if the children do not all have the same parent
- or if the parent is not a subclass of
- .PN compositeWidgetClass .
- .IP \(bu 5
- Returns immediately if the common parent is being destroyed;
- otherwise, for each unique child on the list,
- .PN XtUnmanageChildren
- performs the following:
- .RS
- .IP \- 5
- Ignores the child if it already is unmanaged or is being destroyed,
- and marks it if not.
- .IP \- 5
- If the child is realized,
- it makes it nonvisible by unmapping it.
- .RE
- .IP \(bu 5
- Calls the change_managed routine of the widgets' parent
- after all children have been marked
- if the parent is realized.
- .LP
- .PN XtUnmanageChildren
- does not destroy the child widgets.
- Removing widgets from a parent's managed set is often a temporary banishment,
- and some time later the client may manage the children again.
- To destroy widgets entirely,
- .PN XtDestroyWidget
- should be called instead;
- see Section 2.9.
- .sp
- .LP
- To remove a single child from its parent widget's managed set, use
- .PN XtUnmanageChild .
- .IN "XtUnmanageChild" "" "@DEF@"
- .FD 0
- void XtUnmanageChild(\fIchild\fP)
- .br
- Widget \fIchild\fP;
- .FN
- .IP \fIchild\fP 1i
- Specifies the child. \*(rI
- .LP
- The
- .PN XtUnmanageChild
- function constructs a widget list
- of length 1 and calls
- .PN XtUnmanageChildren .
- .LP
- These functions are low-level routines that are used by generic
- composite widget building routines.
- In addition, composite widgets can provide widget-specific,
- high-level convenience procedures.
-
- .NH 3
- Determining If a Widget Is Managed
- .XS
- \fB\*(SN Determining If a Widget Is Managed\fP
- .XE
- .LP
- To determine the managed state of a given child widget, use
- .PN XtIsManaged .
- .IN "XtIsManaged" "" "@DEF@"
- .FD 0
- Boolean XtIsManaged(\fIw\fP)
- .br
- Widget \fIw\fP\^;
- .FN
- .IP \fIw\fP 1i
- Specifies the widget. \*(oI
- .LP
- The
- .PN XtIsManaged
- function returns
- .PN True
- if the specified widget is of class RectObj or any subclass thereof
- and is managed, or
- .PN False
- otherwise.
-
- .NH 2
- Controlling When Widgets Get Mapped
- .XS
- \fB\*(SN Controlling When Widgets Get Mapped\fP
- .XE
- .LP
- A widget is normally mapped if it is managed.
- However,
- this behavior can be overridden by setting the XtNmappedWhenManaged resource
- for the widget when it is created
- or by setting the \fImap_when_managed\fP field to
- .PN False .
- .sp
- .LP
- To change the value of a given widget's \fImap_when_managed\fP field, use
- .PN XtSetMappedWhenManaged .
- .IN "XtSetMappedWhenManaged" "" "@DEF@"
- .FD 0
- void XtSetMappedWhenManaged(\fIw\fP, \fImap_when_managed\fP)
- .br
- Widget \fIw\fP;
- .br
- Boolean \fImap_when_managed\fP;
- .FN
- .IP \fIw\fP 1i
- Specifies the widget. \*(cI
- .IP \fImap_when_managed\fP 1i
- Specifies a Boolean value that indicates the new value
- that is stored into the widget's \fImap_when_managed\fP
- field.
- .LP
- If the widget is realized and managed
- and if \fImap_when_managed\fP is
- .PN True ,
- .PN XtSetMappedWhenManaged
- maps the window.
- If the widget is realized and managed
- and if \fImap_when_managed\fP is
- .PN False ,
- it unmaps the window.
- .PN XtSetMappedWhenManaged
- is a convenience function that is equivalent to (but slightly faster than)
- calling
- .PN XtSetValues
- and setting the new value for the XtNmappedWhenManaged resource
- then mapping the widget as appropriate.
- As an alternative to using
- .PN XtSetMappedWhenManaged
- to control mapping,
- a client may set \fImapped_when_managed\fP to
- .PN False
- and use
- .PN XtMapWidget
- and
- .PN XtUnmapWidget
- explicitly.
- .sp
- .LP
- To map a widget explicitly, use
- .PN XtMapWidget .
- .IN "XtMapWidget" "" "@DEF@"
- .FD 0
- XtMapWidget(\fIw\fP)
- .br
- Widget \fIw\fP\^;
- .FN
- .IP \fIw\fP 1i
- Specifies the widget. \*(cI
- .LP
- .sp
- To unmap a widget explicitly, use
- .PN XtUnmapWidget .
- .IN "XtUnmapWidget" "" "@DEF@"
- .FD 0
- XtUnmapWidget(\fIw\fP)
- .br
- Widget \fIw\fP\^;
- .FN
- .IP \fIw\fP 1i
- Specifies the widget. \*(cI
-
- .NH 2
- Constrained Composite Widgets
- .XS
- \*(SN Constrained Composite Widgets
- .XE
- .LP
- The Constraint
- widget class is a subclass of
- .PN compositeWidgetClass .
- The name is derived from the fact that constraint widgets
- may manage the geometry
- of their children based on constraints associated with each child.
- These constraints can be as simple as the maximum width and height
- the parent will allow the child to occupy or can be as complicated as
- how other children should change if this child is moved or resized.
- Constraint
- widgets let a parent define constraints as resources that are supplied for their children.
- For example, if the
- Constraint
- parent defines the maximum sizes for its children,
- these new size resources are retrieved for each child as if they were
- resources that were defined by the child widget's class.
- Accordingly,
- constraint resources may be included in the argument list or resource file just
- like any other resource for the child.
- .LP
- Constraint
- widgets have all the responsibilities of normal composite widgets
- and, in addition, must process and act upon the constraint information
- associated with each of their children.
- .LP
- To make it easy for widgets and the \*(xI to keep track of the
- constraints associated with a child,
- every widget has a \fIconstraints\fP field,
- which is the address of a parent-specific structure that contains
- constraint information about the child.
- If a child's parent does not belong to a subclass of
- .PN constraintWidgetClass ,
- then the child's \fIconstraints\fP field is NULL.
- .LP
- Subclasses of
- Constraint
- can add constraint data to the constraint record defined by their superclass.
- To allow this, widget writers should define the constraint
- records in their private .h file by using the same conventions as used for
- widget records.
- For example, a widget class that needs to maintain a maximum
- width and height for each child might define its constraint record as
- follows:
- .LP
- .Ds
- .TA .5i 3i
- .ta .5i 3i
- typedef struct {
- Dimension max_width, max_height;
- } MaxConstraintPart;
-
- typedef struct {
- MaxConstraintPart max;
- } MaxConstraintRecord, *MaxConstraint;
- .De
- .LP
- A subclass of this widget class that also needs to maintain a minimum size would
- define its constraint record as follows:
- .LP
- .Ds
- .TA .5i 3i
- .ta .5i 3i
- typedef struct {
- Dimension min_width, min_height;
- } MinConstraintPart;
-
- typedef struct {
- MaxConstraintPart max;
- MinConstraintPart min;
- } MaxMinConstraintRecord, *MaxMinConstraint;
- .De
- .LP
- Constraints are allocated, initialized, deallocated, and otherwise maintained
- insofar as possible by the \*(xI.
- The Constraint class record part has several entries that facilitate this.
- All entries in
- .PN ConstraintClassPart
- are fields and procedures that are defined and implemented by the parent,
- but they are called whenever actions are performed on the parent's children.
- .LP
- The
- .PN XtCreateWidget
- function uses the \fIconstraint_size\fP field in the parent's class record
- to allocate a constraint record when a child is created.
- .PN XtCreateWidget
- also uses the constraint resources to fill in resource fields in the
- constraint record associated with a child.
- It then calls the constraint initialize procedure so that the parent
- can compute constraint fields that are derived from constraint resources
- and can possibly move or resize the child to conform to the given constraints.
- .LP
- When the
- .PN XtGetValues
- and
- .PN XtSetValues
- functions are executed
- on a child, they use the constraint resources to get the values or
- set the values of constraints associated with that child.
- .PN XtSetValues
- then calls the constraint set_values procedures so that the parent can
- recompute derived constraint fields and move or resize the child
- as appropriate.
- If a
- Constraint
- widget class or any of its superclasses have declared a
- .PN ConstraintClassExtension
- record in the
- .PN ConstraintClassPart
- \fIextension\fP
- fields with a record type of
- .PN \s-1NULLQUARK\s+1
- and the \fIget_values_hook\fP field in
- .IN "get_values_hook procedure"
- .IN "Constraint" "get_values_hook"
- the extension record is non-NULL,
- .PN XtGetValues
- calls the get_values_hook
- procedure(s) to allow the parent to return derived constraint fields.
- .LP
- The
- .PN XtDestroyWidget
- function calls the constraint destroy procedure to deallocate any
- dynamic storage associated with a constraint record.
- The constraint record itself must not be deallocated by the constraint
- destroy procedure;
- .PN XtDestroyWidget
- does this automatically.
- .bp
-