bilbo.geoff@SEAS.UCLA.EDU (Geoff Kuenning) (11/12/87)
Marcel Meth brings up several important issues related to geometry management. I have run into a similar difficulty, which I would like to see addressed in any suggested solution. The problem I have run into deals with initial window sizing. If the user invokes my application with a geometry string, I'd like to obey that. The geometry string controls the sizing of TopLevel, so I'd like to make everything else fit within those confines. This isn't too hard, since the code already exists in my resize routine. But it does require some method of discovering that said code needs to be executed. However, if the user doesn't specify a geometry string, I'd like my application to autosize, possibly depending on the data (for example, an image-processing utility would want to make an image window of appropriate size, then make TopLevel slightly larger to allow room for the other widgets that control the application. In this case, each widget (starting at TopLevel) needs to ask each of its subwidgets for a preferred size and then calculate a preferred size of its own. An easy way to do this would be to add a new routine to the widget class structure, the PreferredSize routine. typedef XtGeometryResult (*XtPreferredSize)(); Widget w; XtWidgetGeometry *constraint; XtWidgetGeometry *reply; Boolean do_resize; The constraint argument would give any limitations the parent widget chooses to place on the child's geometry (for example, TopLevel might choose to limit children to the size of the screen). If a given constraint is unspecified (or for width, height, or border_width, zero), then the child is unconstrained. (Note that these constraints have nothing to do with constrained widgets). The PreferredSize routine would never return XtGeometryAlmost, and it would return XtGeometryNo only if it could not live within the constraints. If the PreferredSize routine returns XtGeometryNo, it must nevertheless store a valid geometry that satisfies the constraints into "reply", so that the caller can choose to ignore the XtGeometryNo result. If the do_resize argument is nonzero, the PreferredSize routine should finish by making an XtGeometryRequest to achieve the desired size. When TopLevel is realized, it can then check to see whether a geometry string was specified. If so, it can call the Resize routines for its children to force them into that size. If not, it can call the PreferredSize routines and then size itself to match. A small related issue here is the problem of doing operations on unrealized widgets. For example, I use popup scroll bars. Before I pop them up, I want to set the thumb using XtScrollbarSetThumb. However, this routine only works after the widget is realized, which also requires it to be managed. So I'd have to clear mapped_when_managed, manage it (to realize it), set the thumb, and then set mapped_when_managed to map it (actually, that part's not implemented yet...). Instead, I modified PaintThumb so that it works on an unrealized scrollbar. I think widget writers need to be very careful to make it possible for various operations to be carried out on unrealized widgets. Special care should be given to the SetValues and GetValues procedures, as well as any "extra" procedures exported to the user. It is frequently necessary to fiddle around with widgets before realizing them, so that you can get the geometry and parameters exactly correct. If you make appropriate XtIsRealized() calls in the right places, you will make your widget much easier to use. Geoff Kuenning geoff@lcc.ucla.edu geoff@ITcorp.com