[comp.windows.x] Help - resizing Athena widgets

kmy@mel.dit.csiro.au (Kid Mun Yap) (01/03/91)

I am currently writing a program using the Athena widget set
and have found that resizing one of the children of a certain
form widget does not cause it (the form widget) to resize itself,
hence causing the child to be clipped off at the right hand edge.
I have a suspicion that this might not be the form widgets
fault and may be due to its parent(s). The following is the
hierarchy of the child widget that was resized :
.... -> TransientShell -> Form -> Core
I have tried :
1)	setting the XtNresizable resource of the child.
2)	XtMakeResizeRequest()
3)	XtSetValues()
4)	XawFormDoLayout()

Could someone tell me how I might be able to resize this widget,
or of any way I might be able to place some Command widgets and
a Core, Viewport or Box (one will do) widget under a popup widget
and have the popup widget resizing to fit all of these when
necessary without having to go into the internals of widgets. 

Thanks in advance.

sundar@ai.mit.edu (Sundar Narasimhan) (01/04/91)

In article <1991Jan3.053442.6086@mel.dit.csiro.au>, kmy@mel.dit.csiro.au (Kid Mun Yap) writes:
|> 
|> I am currently writing a program using the Athena widget set
|> and have found that resizing one of the children of a certain
|> form widget does not cause it (the form widget) to resize itself,
|> hence causing the child to be clipped off at the right hand edge.
I have used something like the following to take care of this for
some time now and am posting it now since I've seen a couple of
posts refer to how difficult dealing with the Form widget's layout
code can be (especially after Resizes). The xt_equalize_geometry() 
function takes a list of widgets, and a direction (either XtNwidth
or XtNheight), finds out the widget with the maximum width or height 
and resizes every widget in the list to that size.

Of course, the idea can be generalized to do other things. (I've
found that with this function I can get around most of the resize
hackery in the Athena Form widget).

Good Luck!
------------------------------------------------------------------
struct _xt_widget_list {
    struct _xt_widget_list *next;
    Widget widget;
};

typedef struct _xt_widget_list *xt_widget_list;
xt_widget_list xt_create_list();

#define W_MAXARGS     20
#define W_STRSIZ      256

xt_equalize_geometry(direction, list)
char *direction;			/* XtNwidth/XtNheight */
xt_widget_list list;
{
    xt_widget_list l;
    Arg args[W_MAXARGS];
    int i = 0;
    Dimension width, height, borderwidth;
    int maxvalue = 0;
    int widflag = 0;

    xt_set_args(args, &i, W_MAXARGS, 
		XtNwidth, &width,
		XtNheight, &height,
		XtNborderWidth, &borderwidth,
		NULL);
    if(strcmp(direction, XtNwidth) == 0) 
      widflag = 1;

    for(l = list; l != NULL; l = l->next) {
	XtGetValues(l->widget, args, i);
	if(widflag) {
	    if (maxvalue < width) maxvalue = width;
	} else
	  if(maxvalue < height) maxvalue = height;
    }

    for(l = list; l != NULL; l = l->next) {
	XtGetValues(l->widget, args, i);
	XtResizeWidget(l->widget, (widflag == 1) ? maxvalue : width,
		       (widflag == 1) ? height : maxvalue,
		       borderwidth);
    }
    return(maxvalue);
}

/*VARARGS*/
xt_set_args(args, i, maxval, va_alist)
Arg args[];
int *i;
int maxval;
va_dcl
{
    va_list  var;
    int      argno;
    String argstr;
    XtArgVal argval;

    va_start(var);
    
    argstr = va_arg(var, char *);

    if(i != NULL) argno = *i;
    else argno = 0;

    while(argstr) {
	argval = va_arg(var, XtArgVal);
	if((argno + 1) > maxval) {
	    fprintf(stderr, "xt_set_args: Arg array overflowed!\n");
	    va_end(var);
	    return -1;
	}
	XtSetArg(args[argno], argstr, argval);
	if(i != NULL)
	  *i = ++argno;
	argstr = va_arg(var, char *);
    }
    va_end(var);
    return 0;
}

/*VARARGS*/
xt_widget_list
xt_create_list(list, va_alist)
xt_widget_list list;
va_dcl
{
    va_list var;
    Widget  w;
    xt_widget_list retval, l;

    va_start(var);
    
    if(list != NULL) retval = list;
    else retval = NULL;

    w = va_arg(var, Widget);
    while(w) {
	l = (xt_widget_list) calloc(sizeof(*retval), 1);
	if(l == NULL) {
	    fprintf(stderr, "create_list: calloc failure\n");
	    exit(0);
	}
	l->widget = w;
	l->next = NULL;

	if(retval == NULL) 
	  retval = l;
	else {
	    l->next = retval;
	    retval = l;
	}
	w = va_arg(var, Widget);
    }
    va_end(var);
    return(retval);
}

xt_free_list(l)
xt_widget_list l;
{
    xt_widget_list temp;
    while(l) {
	temp = l;
	l = l->next;
	free((char *)temp);
    }
}

converse@expo.lcs.mit.EDU (01/05/91)

> Could someone tell me how I might be able to resize [...]
> a  widget under a popup widget
> and have the popup widget resizing to fit all of these when
> necessary without having to go into the internals of widgets. 

The shell widget has a resource named XtNallowShellResize which you
should read about.  It must be set to True, or the shell will deny
resize requests from its child.

As for popups in general, there is an example in the MIT R4 release
in the examples/Xaw directory.


Donna Converse