[comp.windows.x.motif] Resizing with an XmScrolledWindow

tap@stl.stc.co.uk (10/31/90)

Hi All,

   I am trying to get an XmScrolledWindow to size itself correctly to
a given child widget. What I mean by correctly is :-

   1) if only vertical scrolling enabled, size the clip window to
      the width of the child widget. Leave the clip window height
      to whatever default is set.

   2) if only horizontal scrolling enabled, size the clip window
      to the height of the child widget. Leave the width alone

   3) if scrolling in both directions is enabled, set the width
      and height of the clip window to some specified value

   In all of the above I don't muck around with any sizing of the 
ScrollBars. Currently all that happens is that the clipping window
remains it's default size (width = 81, height = 95) whatever I do !


   My application does the following :-

   1) create the XmScrolledWindow widget


   static Arg ViewportArgs[] = {
      {XmNscrollBarPlacement,XmTOP_LEFT},
      {XmNspacing,0},
      {XmNscrollingPolicy,XmAUTOMATIC},
      {XmNscrollBarDisplayPolicy,XmSTATIC},
      {XmNvisualPolicy,XmCONSTANT}
  };

  ...

   widpar = /* parent for the ScrolledWindow, usually an XmRowColumn widget */
   widgetID = (id)XmCreateScrolledWindow(widpar,"Scrollport",
      	       	  ViewportArgs,XtNumber(ViewportArgs));


   2) create the child widget (usually an XmRowColumn) and all subtree widgets


   3) call XtRealizeWidget on the application toplevel widget

   4) get the size of the child widget

      i = 0;
      XtSetArg(args[i],XmNwidth,&width);i++;
      XtSetArg(args[i],XmNheight,&height);i++;
      XtGetValues(child,args,i);


   5) size the ScrolledWindow as stated above, so that it shows the
      required ScrollBars and sizes the clip window correctly

   Part 5) is the bit I can't get right. I have tried :-

   a) get the width/height of the relevent ScrollBars, add this
      to the child width/height and set the XmNwidth,XmNheight
      resources on the ScrolledWindow accordingly

   b) get the value of XmNclipWindow (I think this is an XmDrawingArea widget)
      and set the width/height resources on that widget

   c) set the XmNresizePolicy of the clip window to XmRESIZE_ANY and
      try b). When I ask for the current value of XmNresizePolicy I
      get a value which isn't any of XmRESIZE_NONE,XmRESIZE_GROW,XmRESIZE_ANY !

   d) try a) and b) together

   e) try a) and c) together

   f) muck about with XtQueryGeometry as suggested in the Programmer's
      Reference Manual (p355)

      ...

      XtWidgetGeometry intendedSize,preferredSize;
      XtGeometryMask sizeMask = CWWidth | CWHeight;
      XtGeometryResult geoResult;

      ...

      intendedSize.request_mode = sizeMask;
      intendedSize.width = childWidth;
      intendedSize.height = childHeight;
      XtQueryGeometry(widgetID,&intendedSize,&preferredSize);

      printf("Viewport::realize : preferred size %d %d\n",
      	    preferredSize.width,preferredSize.height);

      geoResult = XtMakeResizeRequest(widgetID,
      	       	     preferredSize.width,preferredSize.height,
      	       	     &(intendedSize.width),&(intendedSize.height));

      printf("Viewport::realize : result %d intended size %d %d\n",
      	       	     geoResult,intendedSize.width,intendedSize.height);

      ...

      I get reasonable values for the preferred size, but the clip window
      doesn't re-size. I don't like this anyway 'cos I am under the
      impression that the QueryGeometry stuff is for internal widget
      implementation not for general application use. While we're here
      the description for XmNvisualPolicy in the Programmer's Reference
      says (p353) :-

      "When the policy is XmCONSTANT ... The only time the viewing area
       can grow is in response to a resize from the ScrolledWindow's
       parent."

      How do/Can/Should I get the parent to issue such a resize request to
      it's child ?


   Any help/ideas on this gratefully accepted. If I'm being dumb, tell me.
   Which brings me to another point. Our bean-counters have cut our Usenet
   feed (in an effort to save some money), so currently if you reply to
   the net I won't see it ! So please reply by e-mail to :-

      T.A.Plant@stl.stc.co.uk

   Thanks


   Environment : Sun 3/60, X11R3 and Motif 1.0

aw@KITCHEN.BELLCORE.COM (Andrew Wason, aw@cellar.bae.bellcore.com) (11/01/90)

mcsun!ukc!stl!tap@uunet.uu.net writes:
>    I am trying to get an XmScrolledWindow to size itself correctly to
> a given child widget. What I mean by correctly is :-
> 
>    1) if only vertical scrolling enabled, size the clip window to
>       the width of the child widget. Leave the clip window height
>       to whatever default is set.
> 
>    2) if only horizontal scrolling enabled, size the clip window
>       to the height of the child widget. Leave the width alone
> 
>    3) if scrolling in both directions is enabled, set the width
>       and height of the clip window to some specified value

I don't know what you mean by "enabled". If your XmNscrollBarDisplayPolicy
is XmAS_NEEDED (see below) then the scrollbars will only be displayed
if your work area widget is too big.  When using XmAUTOMATIC mode,
you don't explicitly enable/disable the scrollbars - they get enabled/disabled
depending on the size of the work area child.


> [...]
>   static Arg ViewportArgs[] = {
>      {XmNscrollBarPlacement,XmTOP_LEFT},
>      {XmNspacing,0},
>      {XmNscrollingPolicy,XmAUTOMATIC},
>      {XmNscrollBarDisplayPolicy,XmSTATIC},
>      {XmNvisualPolicy,XmCONSTANT}
>   };

XmNscrollBarDisplayPolicy should be XmAS_NEEDED or else the
scrollbars will always be displayed.

For your item #1, you want only the vertical scrollbar,
so you must set the width of the XmScrolledWindow to be
the width of the work area. Since you must take into account
the width of the vertical scrollbar too, it is best to use
XtQueryGeometry as the manual suggests:

    intended.request_mode = CWHeight | XtCWQueryOnly;
    intended.height = 75;
    XtQueryGeometry(scrolledWin, &intended, &preferred);
    XtVaSetValues(scrolledWin,
        XmNwidth,   preferred.width,
        NULL);

The XtQueryGeometry will cause scrolledWin to return the correct
width in preferred.width (this is the width which will cause the
horizontal scrollbar to disappear).

For your item #2, you want only the horizontal scrollbar.
You need to do basically the same thing as above, but set
the height of the scrolledWin:

    intended.request_mode = CWWidth | XtCWQueryOnly;
    intended.width = 75;
    XtQueryGeometry(scrolledWin, &intended, &preferred);
    XtVaSetValues(scrolledWin,
        XmNheight,   preferred.height,
        NULL);

For item #3, you want both scrollbars, so just set
the width/height of scrolledWin to be less than the width/height
of your work area child.

Andrew

--------------------------------------------------------------------------------
Andrew Wason                                        Bell Communications Research
aw@cellar.bae.bellcore.com                          Piscataway, NJ
bellcore!cellar!aw