@begin(header)
author: Mark S. Ackerman
show_author: ShowNone
author_organization: MIT Center for Coordination Science
node_expert: ackerman=ag@ics.uci.edu
expiration_date: 12/31/93
last_modifier: ackerman@ics.uci.edu
last_mod_date: 08/28/91
mod_num: 2
@end(header)

@begin(M)
The form widget is a slippery character and is difficult to describe and
understand, we are looking into getting something better, but for a while
for doing general widget layout the form is it.  So to let people use it more
effectively I will try to give a better explanation of its use.

The form has two distinct methods of laying itself out.  Method 1 never
resizes the children of the form, and just attempts to place them in next
to each other like building blocks, according to the resources shown below.
The FromVert resource is used to place this widget directly below one of its
siblings.  The fromHoriz resource is used to place this widget directly to the
right of one of its siblings.  This method is used when managing and unmanaging
children, and processing childrens geometry requests.

Method 2 may resize children if the XtNresizable constraint resouce is set
for that child.  This method takes each edge of each child, and moves it 
appropriately, for instance in the above example you may want to 
chain both the top and bottom edges of the lable widget to the top of the
form.  This will of course keep it from changing size, and both edges are
fixed to the top of the form.  For really strange behavior you can chain the
top of a widget to the bottom of the form, and the bottom of a widget to the 
top of the form.  This method is only used when the form is told to resize
itself by its parent.

Resources for each method of laying out the form widgets children.

Method 1				Method 2
--------------------------------------------------------------
XtNfromVert				XtNbottom
XtNfromHoriz				XtNtop
XtNhorizDistance			XtNleft
XtNvertDistance				XtNright
					XtNresizeable


Chris Peterson
@end(M)

@begin(M)
Subject: Re: Form Widget
Date: Thu, 29 Dec 88 15:24:29 EST
From: Chris D. Peterson

> One other question -- how is the value of XtNwidth used? 

Both the Athena Dialog and the Athena Form widget ignore their width
and height arguments.

Since the Dialog is a sub_class of the form if you want to know exactly how 
either of these will be layed out consult the Xt Athena Widget Set
documentation on the Form widget.  

						Chris D. Peterson     
						MIT X Consortium /
						Project Athena 

@end(M)
@begin(M)
Organization: DEC/MIT Project Athena
Date: Wed, 04 Jan 89 09:49:06 EST
From: Ralph R. Swick 

     The scenario is similar: a form with three command widgets, all 150 pixels
     wide (random strings as labels).  After you create these widgets, toggle
     the XtNsensitive attribute on one of the widgets.  For some reason, the
     form seems to think that the widget needs resizing and it shrink's the
     width to the minimum according to the string.
     
Slightly different issue here.  It's not the Form that's causing the
problem but rather the Command (Label) itself.  By default, every time
you do a SetValues on a Command (Label), it will make a geometry request
to be resized to its optimal dimensions.  There are two ways to
disable this: the XtNresize resource in Command (Label), or the
XtNresizable constraint resource in Form.  The former is documented,
the latter is mentioned but not well documented.  Since the default
value for the latter is to disallow geometry requests from the child,
you must have already discovered it.
@end(M)

@begin(M)
Subject: Re: precisely placing a child within a form widget 
Date: Tue, 18 Apr 89 14:24:17 EDT
From: Chris D. Peterson 


> In my code, I state the exact size I would like the viewport widget to
> be, and where the viewport widget should be placed relative to a
> scrollbar widget which is also within the same form widget.  To do
> this I use XtNheight, XtNwidth, XtNfromHoriz and XtNhorizDistance.
> Well, the viewport widget gets drawn starting in the proper place, but
> it extends clear to the right edge of the form widget, rather than
> limiting itself to the width I stated in XtNwidth.

> All right experts, what's the real solution??

Try setting the left and right edges of the Viewport to XtChainLeft
and the top and bottom edges to XtChainTop.  This should keep it from 
resizing.


                                                Chris D. Peterson
                                                MIT X Consortium

@end(M)

@begin(Q)
Date: 25 Apr 89 03:43:04 GMT
Subject: Athena Form Widget Bug?

I have just tried Form Widgets, and I don't think they work.
Here is what I want to do:
	a) create a form widget.
	b) add 3 labels, positioned as I want.
	c) make the labels un-resizable.
	
Here is what happens:
	a) the labels get created.
	b) they are the wrong size (I ask for 25x30, the estimated
		actual size is 100x100)
	c) they resize when the window is resized.

Is this a bug?  You tell me, please.  I would love to know what
I am doing wrong.  
@end(Q)

@begin(A)
Subject: Re: Athena Form Widget Bug? 
Organization: X Consortium, MIT Laboratory for Computer Science
Date: Thu, 27 Apr 89 13:05:32 EDT


>Here is what I want to do:
>	a) create a form widget.
>	b) add 3 labels, positioned as I want.
>	c) make the labels un-resizable.
	
>Here is what happens:
>	a) the labels get created.
>	b) they are the wrong size (I ask for 25x30, the estimated
>		actual size is 100x100)
>	c) they resize when the window is resized.

Read the very recent posting of Chris Peterson,
Re: dialog, label, and transient shell widget problems
It contains a description of the form widget resources which 
will answer your questions.

Try 
XtSetArg(arg[n], XtNtop, XtChainTop); n++;
XtSetArg(arg[n], XtNleft, XtChainLeft); n++;
XtSetArg(arg[n], XtNbottom, XtChainTop); n++;
XtSetArg(arg[n], XtNright, XtChainLeft); n++;

The labels will have the originally requested
size, and will not resize, when this code is
added to your original example code.
@end(A)

@begin(M)
> >Now comes the problem.  When I delete one of the subordinate ... widgets
> >with XtDestroyWidget, the parent form widget resizes itself smaller.  This
> >is to be expected, I suppose, except that it seems to over do it.  It then
> >proceeds to reduce the ... size of each of the remaining subordinate
> >... widgets.  This continues happening each time I destroy a subordinate
> >... widget until some minimum ... size for each sub[widget] is aparently
> >reached.  At this point, it is impossible to read the text inside the ...
> >widgets because they are so [small].
> 


I have found that in working with widgets one must "chain" them to the
parent widget, or they get hosed when sizes change.  I added the following
arguments to command_args[] and it works pretty well (when you destroy
the subwidgets the parent doesn't get any smaller, which is what was happening
before adding these constraints). 

I confess that there may be a more appropriate way to do this, but this seems
to work.

    static Arg command_args[] = {
        { XtNfromVert, (XtArgVal) NULL },
        { XtNcallback, (XtArgVal)callbacks },
        { XtNwidth, (XtArgVal)130 },
        { XtNtop, (XtArgVal)XtChainTop},
        { XtNbottom, (XtArgVal)XtChainTop},
        { XtNleft, (XtArgVal)XtChainLeft },
        { XtNright, (XtArgVal)XtChainLeft },
     };

@end(M)

@begin(M)
Subject: Re: Form Widget question 
Organization: X Consortium, MIT Laboratory for Computer Science
Date: Fri, 14 Jul 89 11:20:04 -0400


> I have a Form Widget with (let's say) two buttons in it.
> How can I stick a third button between the first two? 

The following resources presuppose the order of widget creation to be
leftButton, middleButton, rightButton.

Demo.form.middleButton.fromHoriz:	leftButton
Demo.form.rightButton.fromHoriz:	middleButton

At the time that the right button is created, the Athena form widget 
converts middleButton to a widget ID.  So, the middle button must be
created before the right button.

If the order of widget creation is leftButton, rightButton, middleButton,
write the resources so that the placement of buttons depend only on
existing buttons.

Demo.form.middleButton.fromHoriz:	leftButton
Demo.form.rightButton.fromHoriz:	leftButton
Demo.form.rightButton.horizDistance:	60

Not very elegant, is it?

Donna Converse
@end(M)

@begin(M)
Subject: Re: dialog, label, and transient shell widget problems 
Date: Fri, 28 Apr 89 10:51:25 EDT
From: Chris D. Peterson 


> I redid it using a label and command widgets in a form.  That worked
> fine, except that the label widget doesn't resize...

> Actually, the behaviour I'm seeking is resizing the label widget when the
> label text is changed.  I changed the label to a large one (more
> characters), but the label widget remained the same size.


The problem is that the Form is denying geometry requests from the label.
This is sometimes very useful, but not what you want.  There is a
constraint resource in the Form widget called XtNresizable.  Set it to 
TRUE.

						Chris

@end(M)

@begin(Q)
Subject: Form widget question

I am trying to make a Form widget with three daughter widgets like
this:

	+------+------+
	|    Label    |
	+------+------+
	|      |      |
	| Form | Form |
	|______|______|

but I keep winding up with this:

	+------++-----+
	| Label |     |
	+------++-----+
	|      |      |
	| Form | Form |
	|______|______|

I can't find any way, short of setting the initial size of the Label
widget to some large value, to center the Label in the enclosing Form.
I have tried setting
	XtNright <- XtChainRight
	XtNleft <- XtChainLeft
in the Label widget, with no change in behavior, and I think that
makes sense, but it still doesn't solve my problem.

@end(Q)

@begin(A)

Subject: Re: Form widget question 
Date: Fri, 16 Dec 88 14:41:18 EST
From: Chris D. Peterson


> 
> [picture deleted, basically trying to get a label widget to be the 
>  titlebar over two forms, so that it extends across both of the daughter 
>  forms.]
>
> I can't find any way, short of setting the initial size of the Label
> widget to some large value, to center the Label in the enclosing Form.
> I have tried setting
> 	XtNright <- XtChainRight
> 	XtNleft <- XtChainLeft
> in the Label widget, with no change in behavior, and I think that
> makes sense, but it still doesn't solve my problem.

The form widget is a slippery character and is difficult to describe and
understand, we are looking into getting something better, but for a while
for doing general widget layout the form is it.  So to let people use it more
effectively I will try to give a better explanation of its use.

The form has two distinct methods of laying itself out.  Method 1 never
resizes the children of the form, and just attempts to place them in next
to each other like building blocks, according to the resources shown below.
The FromVert resource is used to place this widget directly below one of its
siblings.  The fromHoriz resource is used to place this widget directly to the
right of one of its siblings.  This method is used when managing and unmanaging
children, and processing childrens geometry requests.

Method 2 may resize children if the XtNresizable constraint resouce is set
for that child.  This method takes each edge of each child, and moves it 
appropriately, for instance in the above example you may want to 
chain both the top and bottom edges of the lable widget to the top of the
form.  This will of course keep it from changing size, and both edges are
fixed to the top of the form.  For really strange behavior you can chain the
top of a widget to the bottom of the form, and the bottom of a widget to the 
top of the form.  This method is only used when the form is told to resize
itself by its parent.

Resources for each method of laying out the form widgets children.

Method 1				Method 2
--------------------------------------------------------------
XtNfromVert				XtNbottom
XtNfromHoriz				XtNtop
XtNhorizDistance			XtNleft
XtNvertDistance				XtNright
					XtNresizeable

Back to the specific question:

The only way to get the label widget to go all the way across the form 
like you are asking is to size it appropriately.  This can be done by querying
the daughter form widgets of their sizes (a call to XtFormDoLayout may be
necessary) and the label widget of its XtNhorizDistance resource, and adding
them all together as the correct size of the label widget.

						Chris D. Peterson     
						MIT X Consortium /
						Project Athena 


@end(A)

@begin(M)
Subject: Re: Problem with Xaw Form and Box widgets 
Date: Tue, 25 Jul 89 15:57:31 -0400
From: Chris D. Peterson

[picture deleted]

> The "canvas" widget is a Label (for now) and should resize in conjunction with
> its parent Form.  I'd like button-box to maintain a fixed size based on the 
> font used in its command buttons.  I've tried button-box as both a Box
> and a Form widget.  In both cases it resizes when I resize its parent Form,
> even if I've set the XtNresizable attribute to false for button-box and the
> buttons inside it.  

Try setting the XtNleft and XtNright resources for the label to XtChainLeft, and
the XtNtop and XtNbottom resources to XtChainBottom.  This will keep it the 
same size.
 
>     Two questions:
> 1)  Does XtNresizable really work?

Yes, but it is intended to be used by the form to determine whether or not
to listen to resize requests from its children.  Setting it to FALSE does not
mean that the children will never be resized, it means that they can never
ask to be resized.  The form may do anything it wants to its children.

> 2)  Is there a way to force all buttons in a Box widget to stay on the same
>     row?  Just making the box wide enough (XtNwidth) doesn't seem to work.

Nope, use the Form or the VPaned.

						Chris D. Peterson     
						MIT X Consortium 

@end(M)

@begin(M)
Subject: Re: Form problem 
Date: Mon, 12 Feb 90 11:40:25 -0500


> 	I am having a small problem with the form widget.  After I create a
> ManagedChild on the form widget and try to move the widget by XtMoveWidget,
> and then setting the XtSetValues with the new coordinates, upon
> creating another widget onto the form causes the original widget to
> move back to it created location.  Is there any way I can change the
> coordinates of an exisiting widget permanently?

Don't do that.

The Form widget's geometry manager will place its children where it
believes is apropriate, given the size and location of each of the
other children.  You can control the order of the children and their
relative positions (i.e. this widget will be below that widget, and to
the right of this other widget) but you cannot specify an exact
placement.  The Form widget does not support it.

So what can you do about this?  You have two choices, either find a
composite widget that does what you want, or write one yourself.
Trying to force a composite to do something it wasn't designed for is
just asking for trouble.

Also:

Don't use XtMoveWidget.  This function is reserved for the exclusive
use of Parent widgets to move their children around.  Application
programmers should use the SetValues Interface only.  If you can't do
it with XtSetValues then you probabally are doing something you
shouldn't, and you'll more than likely confuse this widget's Parent,
causing strange behavior on resize.


						Chris D. Peterson     
						MIT X Consortium 
@end(M)

@begin(M)

Subject: Re: Help with child positioning in Form widgets 
Organization: DEC/MIT Project Athena
Date: Mon, 30 Jan 89 13:19:31 EST
From: Ralph R. Swick 

     ... XtNhorizDistance and
     XtNvertDistance (to specify the distance).

     ... *always* creates children to the right of or below
     the reference child. Is it possible to position a new child above or
     to the left of the original using these or other widget attributes?

     I have already tried negative distance specification.
     I am using Athena widgets.

Gee, the following two lines added to a resource file seem to do the
right thing to clients/xclipboard (which uses the form widget), when
used in conjunction with the default app-defaults file (XClipboard.ad):

  XClipboard.shell.quit.horizDistance: 100
  XClipboard.shell.erase.horizDistance: -100

Moral: Negative distances should work.  
@end(M)

@begin(Q)
I am trying to use r4 Athean Widgets to make some custom menu-like and
dialog-type interface things. When I use the ChainRight to get my text
field to go all the way across the dialog, it sits on the left.  When
I use ChainRight to get the cancel button to stay left, it stays on
the right next to the ok button.  Is there a fix for this?
@end(Q)

@begin(A)
Subject: Re: ChainRight w/Xaw(r4) Form Widget 
Date: Tue, 12 Jun 90 13:32:02 -0400


Unfortunately the Athena Form widget will probabally not do what you
want.  The XawChain<something> resources are not used when the form is
originally laying out the widget, only when the widgets are resized.
I suggest that you read the R4 Xaw documentation about the Form
widget's layout policy.  It is pretty clear about what it can and
cannot do.

Remember that you can chain the left and right edges of a child of the
Form independently.

						Chris D. Peterson     
						MIT X Consortium 
@end(A)

@begin(M)
Subject: Re: Achieving constant thickness scrollbars under resizeable form. 
Date: Fri, 17 Aug 90 13:02:52 EDT
From: Ralph Swick 

This should be easy to do.  Remember, there are 4 edges to each
child and you can chain each one independently.

	   2) are created with Resizeable == False, i.e. not to be
	      resized when form is resized.

Actually, Form/XtNresizeable says whether or not the child is
allowed to request a geometry change; it has nothing to do
with what happens when the Form itself is resized.

       * The vertical scrollbar is separated by the fromVert
       ...

Did you say these backwards, by any chance?  The mental picture
I draw is a bit peculiar, but maybe it is really what you
intend; no matter...

Chaining both the top and bottom of the horizontal scrollbar
to the form bottom and both the left and right of the vertical
scrollbar to the form left should cause their thicknesses to
remain constant.  I rather suspect your resize algorithm
can be completely specified as resources.
@end(M)

@begin(M)
Date: 4 Oct 90 11:34:07 GMT
From: (Richard Hesketh)
Organization: Computing Lab, University of Kent at Canterbury, UK.
Subject: Re: Resetting fromHoriz or fromVert resources

>The label widgets are placed in a form widget inside of a viewport
>widget inside of a toplevelShell widget.  After the descriptions, I'll
>include the declarations of the resources for these widgets.

>When I first create/place a label widget, everything works okay, i.e., the
>scrollbars are correct.  However, I am pretty printing the tree, e.g.,
>
>	       root
>	        |
>   -----------------------------
>   |            |              |
>child1	      child2        child3
>                |
>	   -----------
>	   |         |
>	child2.1  child2.2
>
>Pretty printing takes place as such for child2.1 for example:
>I want to place myself relative to the rightmost widget that I've seen
>so far (in a postfix traversal), in this case - child1.
>
>I get the x and width values of child1
>I get the x value of child2.1
>
>if I need to change the x value of child2.1, I make it 10 pixels + the
>x and width values of child1.
>
>I move the child2.1 widget with XtMoveWidget.
>What I want to do is just reset the fromHoriz resource, but nothing
>happens when I do this.  Any ideas?

By using the XtMoveWidget() you are completely overriding any child layout
performed by the Form widget.  The from{Horiz|Vert} resources are widget
id.s (not positions) and are used in conjunction with the other constraint
resources to tell the form how to layout the individual child.  The children
should never be moved using the XtMoveWidget() directly in an application.
XtMoveWidget() should only be used by a widget class itself to move its own
children around.

[ Ref: Athena Widget Set - C Language Interface Manual by Chris Peterson;
  Section 6.0.1: "Under no circumstances should an application programmer
  resort to XtMoveWidget() or XtResizeWidget(); these functions are
  excusively for the use of Composite widget implemetors." ]

>ANyway, because I am using XtMoveWidget one of two (or both) problems
>occur:

Again, this is all because you are breaking the whole geometry management
procedure implemented by the toolkit.  All application geometry changes
should be made through the SetValues interface which will then perform the
necessary changes and inform the various parents involved.

>Thanks for any explanation!

I would suggest two possible solutions:

1) Use the constraint resources of the Form to position children relative to
   siblings.  Such as:

	XtVaSetValues(child1, XtNfromVert, root, XtNfromHoriz, NULL,
			XtNvertDistance, Y_SEP_DIST, NULL);
	XtVaSetValues(child2, XtNfromVert, root, XtNfromHoriz, child1,
			XtNvertDistance, Y_SEP_DIST,
			XtNhorizDistance, X_SEP_DIST, NULL);
	followed by:
		XtUnmanageChild(child1);
		XtManageChild(child1);
	[ see notes below ]

2) Write your own constraint widget class that lays out its given children in
   a tree.  Probably a good place to start for this is the Tree Widget in
   Doug Young's book "X Window Systems Programming and Applications with Xt"
   (there's also a Motif version) published by Prentice-Hall.
   You could implement the algorithm recently published in July's edition of
   IEEE Software: "Drawing Dynamic Trees" by Sven Moen.  Then you could also
   give it away 8-}.

---

A couple of common things to note:

1) The Form widget has a bug in it such that changes to constraint resources
   on children do not cause the parent to re-layout them immediately.  This
   re-layout can be forced by unmanaging and them re-managing the changed
   child.

2) The Viewport widget will not let the child (in this case a Form) scroll
   itself.  Thus changes in the x and y positions of the child are refused.

---

Richard Hesketh   
Computing Officer, Computing Lab., University of Kent at Canterbury,
Canterbury, Kent, CT2 7NF, United Kingdom.
        Tel: +44 227 764000 ext 7620/7590      Fax: +44 227 762811


Date: 4 Oct 90 12:35:26 GMT
From: (Richard Hesketh)
Organization: Computing Lab, University of Kent at Canterbury, UK.
Subject: Re: Resetting fromHoriz or fromVert resources


>1) The Form widget has a bug in it such that changes to constraint resources
>   on children do not cause the parent to re-layout them immediately.  This
>   re-layout can be forced by unmanaging and them re-managing the changed
>   child.

What I should have said really is that this is a *feature* of the Form
and that an (in)convenience routine is available to force or defer a
re-layout of the form; namely XawFormDoLayout().
IMHO this ought to be a *public* Boolean resource that can be toggled.

Richard
@end(M)

