[GUI] Dynamic ... something
Wolfgang Thaller
wolfgang.thaller@gmx.net
Sat, 12 Apr 2003 18:54:13 +0200
Glynn Clements wrote:
> 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.
I agree that the use of fixed placement should be strongly discouraged.
I would want the feature to be in the CGA anyway, mainly for two
reasons:
a) as a base to implement automatic layout on, at least for platforms
that don't provide their own automatic layout features (Mac OS, Windows)
b) because it is really easy to implement - it would be very useful for
testing in the early phases of CGA development.
> 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.
I actually agree, but I think it shouldn't be the only way.
Personally, I'd be happy to use Apple's Interface Builder to draw the
interface of my Haskell programs.
However, I'd sometimes prefer to have a slightly sub-optimal Mac
version (interface created using automatic layout algorithms from the
Mac backend of the CGA) than not to have a Mac version at all, which
would mean I'd have to use the GTK or Motif versions via [local] X11 on
my Mac (--> even less native look&feel).
Then, there's the issue of dynamically-generated interfaces - we need
programmatical automatic placement in that case.
> 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.
Which brings us to another problem; the mechanisms for interfacing
interface files with the rest of the program are vastly different:
Motif/UIL/UID: (just what I heard on this list, I really no nothing)
Each widget can be identified by its name.
Callbacks referenced from the interface file are specified using a
name. When loading the interface, a name/value mapping has to be
provided.
Other data (examples please... images?) may be provided in the same way
Windows Resource files:
Each widget can be identified by its numeric ID.
You can't define separate callbacks for different widgets; instead, you
define one for the entire dialog, which gets passed, which can take
decisions based on the clicked button's ID.
Only fixed layout is supported, no resizing.
Resizable windows like document windows are usually created
programmatically.
Macintosh Carbon (nib files):
Each widget ("control") inside a window/dialog box has an ID that
consists of a four-character-code and a numeric ID.
For each control, you can also set a four-character "command ID" that
gets sent to the callback when e.g. a button is pressed.
Only fixed coordinates are supported, no resizing.
Resizable windows like document windows are usually created
programmatically.
Macintosh Cocoa (nib files):
You usually don't identify individual widgets from the outside.
Instead, you connect an objects "outlet" to the widget. When the nib
file is loaded, the object is instantiated dynamically and a member
variable is set to point to the widget.
Only fixed coordinates are supported, but you can specify how the
widget should react if its container is resized (stretch, stay on left,
stay on right, stay in center etc...).
Document windows are created from nib files, too (not programmatically).
I currently don't see how those differences can be reconciled without
a) requiring platform-specific code
b) sacrificing features
or c) both of the above :-(
None of the approaches need to be mutually exclusive, though:
1) Explicit placement
(should not be used directly except in some strange case that I just
can't think of)
2) Platform-specific interface definition files
3) Dynamic layout
For 3), I'm thinking of a high-level approach.
Of course, there'd be the usual grid-based mechanisms (cf Java's
GridBagLayout), but I'm also thinking of specialized layouts for
special situations - like a "button bar" in a dialog box, where you
just tell the layout manager which button is the OK button and which is
the Cancel button and so on.
I'd implement this in Haskell, on top of 1); I'd tweak the algorithms
separately for each platform. For platforms with good support for
dynamic layout, we might be able to do it on top of "native" features.
> 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.
So let's not impose anything - but we might still want to provide it.
Most style guide differences can probably be resolved by the right kind
of abstraction (e.g. button ordering, sizing & spacing).
Maybe I'd develop my programs on the Mac, and then move them over to
Motif and only manually redo the layout where it needs fixing. I'm sure
that it's possible to get "perfect" platform-independent layout for
simple forms...
(If it turns out to be absolutely impossible to create results that we
can be happy with, we can still leave it out...)
Cheers,
Wolfgang