beautypg.com

Crunch CRiSP File Editor 6 User Manual

Page 61

background image

Page 61

When laying out a dialog box, CRiSP tries hard to avoid objects from overlapping, so it is normally safe to
use the DBOX_ANCHOR attributes even if there are objects to the left, right, top or bottom of the specified
object.

With what has been described so far, it is possible to describe fairly abstract dialog boxes where we do not
care too much about the fine level of detail in a dialog box, and thus we can be reasonably user and
environment independent.

One of the major missing features from the discussion so far is a fine degree of granularity. For example,
consider a case where we want to have two list boxes side by side. This is easily supported in CRiSP and it
is easy to ensure that the list boxes are allocated 50% of the space each. (It is not possible to specify that
one list box has 25% of the space and another 75% of the space). Now consider putting a label object or an
input field above each of the list boxes. The width and characteristics of a label are not the same as a list,
and without hardcoding exact pixel widths it is difficult to ensure that the labels or fields are exactly the same
widths as the list boxes beneath them, especially after a resize operation.

In order to handle this type of fine level layout, we need to implement a mechanism for constraint
management. Constraint management is a way of giving hints to say things like: "Object X is to be exactly as
wide as Object Y", or "Make Object X and Object Y align with each other on the bottom side" (e.g. placing a
label field aligned to the left and to the bottom of a multiline list box).

Constraint definitions is a very powerful area but it is exceptionally easy to create constraint definitions which
are impossible to satisfy leading to incorrect looking displays. Worse, it is very difficult for the human mind to
understand why the layout is not as you expect. Therefore, when using constraints, you should be very
careful and try one thing at a time.

The constraint mechanism with CRiSP is loosely based around the Form widget available in the Motif
programming API. The Form widget implements a mechanism for stretchability, which allows an objects size
and position to be tied to any other object in the dialog box. The way this works involves a number of
attributes, but essentially works like this. When you create an object you can tell CRiSP that the top, bottom,
left or right hand side of the object is attached to the top, bottom, left or right of some other object in the
dialog box. For example, lets take the case of a single line input field, which we want to place above a
multiline list box. If we want the input field to be exactly the same width as the list box, then what we want to
say is something like this: the left hand side of the input field has the same X co-ordinate as the left hand
side of the multiline list box, and also at the same time the right hand side of the input field has the same X
co-ordinate as the right hand side of the list box.

In order for this to work properly, in this case, we would also need to tell CRiSP that the input field is
stretchable. (We do this with the DBOX_ALLOW_RESIZE attribute). If we did not make the input field
stretchable, then it is a bit like try to stretch a wooden ruler - you cannot, and you end up with something
which is not as you expected. Sometimes it is reasonable for an object to be stretchable, sometimes it is not.
Normally, stretchability is important when you want the objects within the dialog box to act like pieces or
rubber. An example where stretchability is normally inappropriate is for buttons, but these are catered for
using the DBOX_CENTERED attribute as described in the previous section.

Now the complexity comes because you now have 4 sides to your object which can be combined to refer to
the 4 sides of any other object, or even any 4 distinct objects. Therefore, you have enough rope to hang
yourself, and you should handle constraint properties very carefully as it is very easy to specify impossible
conditions, such as constraining the layout of an object to itself.

As well as being able to constrain an object so that its size or position is with respect to some other object,
you can also constrain an object so that it maintains some fixed distance from the edges of the dialog box.
This in effect gives a similar effect to that previously described for the DBOX_ANCHOR_xxx attributes
described, but is slightly more functional.

The following example illustrates some of these points. Consider the case of a dialog box, which has an
input field, beneath which is a list box. The input field is constrained to be the same width as the list box, and
beneath the list box is an Ok and a Cancel button:

obj_id = create_object(make_list(
/* Give a title to the dialog box. */
DBOX_TITLE, "Constraints Example",

/* Macro to callback when user does things */
/* in the dialog box. */
DBOX_CALLBACK, "callback_macro",