
Wolfgang Thaller wrote:
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
Essentially UIL has the same problem as X resources: all values are strings, so you can only specify values for attribute types which can be converted from strings. Strings (e.g. for labels), fonts, colours, numeric and enumerated types aren't a problem; the problem comes when you want to set an attribute whose value is a pointer, XID (basically a handle) etc. Images (both Pixmap and XImage types) suffer from a related problem. Specifically, you can't easily specify a value for an image attribute (e.g. XmNbackgroundPixmap) at widget creation time; the reason is that any images have to be compatible with the visual used for the widget's window, but the widget hasn't been realised (its window hasn't been created) at that point, so you can't easily discover the correct visual. Some widget sets (e.g. some of the Athena variants) do allow you to specify images at widget creation time; typically, they assume that the widget's window will use the default visual. This works fine on a typical Linux box, where the display only has one visual, but falls down on more complex hardware (e.g. SGIs) where multiple visuals are available (the program dies with a BadMatch error as soon as the window is realised).
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 :-(
Neither do I. Which is why I'm so keen to see an API which separates the initialisation from the core application logic. The application logic needs to be provided with handles to any widgets which it needs to query or manipulate, and it needs an interface through which to do so. That's all. The code doesn't need to know anything about how those widgets were laid out; or even exactly what types of widget its dealing with, so long as it can perform the necessary operations. Real-world applications seldom achieve portability by using only portable libraries (e.g. OpenGL + GLUT). It's far more common to write portable code where possible, and accept that some (hopefully small) portion of the code will need to be re-written for each platform. To me, the most important part to get right initially is the stuff which interfaces with the application logic, because that tends to be scattered throughout the code. Primarily state management; not just the generic set/get interface, but the semantics of common widget types (e.g. how do you specify a scrollbar position?). Although it seems counter-intuitive, the mechanics of UI construction aren't so important, as it's relatively straightforward to isolate that to a separate file, and the code tends to be highly idiomatic; the differences between a typical BuildTheUI() function (which is code) and e.g. UIL (which is data) tend to be more syntactic than structural.
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.
That's one case you probably don't need to handle. OK/Cancel dialogs
should be available as complete components; if they are available,
they should be used.
--
Glynn Clements