[GUI] Dynamic ... something

Glynn Clements glynn.clements@virgin.net
Sat, 12 Apr 2003 16:25:35 +0100


Wolfgang Thaller wrote:

> So allow me to try to summarize the discussion about dynamic layout:
> 
> We'll have one or more of the following (correct me if I left something 
> out, or if I'm misrepresenting something):

For Xt (Athena, Motif), you have a choice of:

1. Programmatic creation of widgets with programmatic specification of
layout attributes.

2. Programmatic creation of widgets with layout attributes taken from
X resources.

For Motif, you have some additional choices:

3. Creation of widgets from UID (compiled UIL) files, with layout
attributes specified in the UIL/UID files.

4. Creation of widgets from UID (compiled UIL) files, with layout
attributes taken from X resources.

In all four cases, the set of available layout attributes depends upon
the widget's parent (container). Some (e.g. XmRowColumn) have minimal
or no layout attributes; others (e.g. XmForm) have extensive layout
attributes. For XmForm, absolute positioning is just one possible
option (effectively, the top/left attachments are to the edges of the
parent, with offsets specified in pixels).

> Something like:
> nib <- loadAppleNibFile_MAC "foo.nib" -- a nib file is a document 
> created by Apple's Interface Builder and contains one or more dialogs
> dialog <- createDialogFromNib_MAC nib "MyDialog"
> If "MyDialog" doesn't refer to a dialog in the file, a runtime error 
> occurs...

For UIL, you also have to provide definitions for any attribute values
which can't be specified inside a UIL file (e.g. pointers, callbacks). 
Basically, the UIL file uses symbolic names, and you provide a list of
name/value pairs to map the names to specific values when loading the
file.

> What about making layout management a feature of a containter widget?
> When adding widgets to a FixedLayoutContainer, you'd have to specify 
> the coordinates, when adding widgets to a GridLayoutContainer, you'd 
> specify row & column, etc.
> We could start with just a FixedLayoutContainer (that's easy), and then 
> we can go on and add "more intelligent" layout mechanisms.

Specifying fixed coordinates is likely to violate native look-and-feel
(you have no idea what the default font is), and will break down if
the application is customised (e.g. changing labels).

Allowing fixed-coordinate layouts is an open invitation for people to
write code which only works correctly on their system; they will just
tweak the numbers until it looks correct with their preferences.

> Another, similar approach would be to make the "layout manager" an 
> _attribute_ of a container widget (as is done in Java's AWT, if I 
> remember correctly). Don't know if that has any advantages for our 
> situation.

Java's AWT is a great way to write programs which are instantly
recognisable as "Java AWT" programs (i.e. instantly distinguishable
from "native" programs).

If you want native l&f, you have to redo the layout for each platform. 
If you try to impose a portable solution, you'll end up with something
that doesn't have native l&f on anything. Even if all of the common
platforms provided exactly the same layout interface, unless they also
had identical style guides, you would need to re-implement the layout
for each platform.

The easiest way to get both portability and native l&f is to use
external interface definitions. The interface definitions themselves
aren't remotely portable, but at least it keeps the non-portability
out of the actual code.

Of course, people may ultimately decide that native l&f is just too
much work, and abandon it. It's certainly an option. But, if native
l&f is abandoned, it should be a conscious decision, rather than a
accidental consequence of not realising what's involved until too
late. Also, it makes it less likely that the end result will actually
be the one-and-only UI library; if Haskell is around long enough,
eventually someone may want native l&f badly enough to implement a
library which provides it.

-- 
Glynn Clements <glynn.clements@virgin.net>