marbru@auto-trol.UUCP (Martin Brunecky) (03/14/90)
A few weeks ago, comp.windows.x carried a discussion of the advantages and disadvantages of UIL. Some people suggested that UIL is essentially useless, that the X resource database is enough, while others have pointed out that there are things you cannot do with the database alone, such as definition of a widget tree, callbacks, compound strings etc. Prompted by this discussion, I have put together some code which, in my belief, extends the the X Resource Database so that an ENTIRE USER INTERFACE can be defined (and customized) within the database. This avoidins the need for multiple sources of user interface definition by replacing UIL. I am posting an overview of this "POOR MAN'S UIL" here to get some feedback on. If there is enough interest, I can post the code, which has been tested with Motif and other widgets on SPARC, Ultrix/RISC and VMS/VAX, on comp.sources.x. To start, let me present a simple example of an application-class X resource file for a Motif based HelloWorld: # # shell - an application shell, containing RowColumn organizer # HelloWorld.managed.child_0: box,xmRowColumn # # box - the main container, contains label and button # Helloworld.box.spacing: 8 HelloWorld.box.managed.child_0: label,xmLabel HelloWorld.box.managed.child_1: button,xmPushButton # # label # HelloWorld.box.label.labelString: Hello, WORLD ! # # button # HelloWorld.box.button.labelString: Push ME HelloWorld.box.button.activateCallback: push(Push again to EXIT) # Except for the top-level shell creation, there is NO widget creation code in my HelloWorld. The entire widget tree definition is shown above. For any widget, I can specify any number of children with all their resources, and all recursively. Callbacks are specified in a similar way, by passing a string argument as call data. Note the example is a starting point: It does NOT show all the functionality such as deffered subtree creation, manage/unmanage callbacks, etc... APPLICATION CODE IMPACT A runtime interpreter must be able to translate X resource database strings into widget classes (or widget creation routines), and callbacks. Even though some systems (VMS for example) allow dynamic binding, the current implementation uses registration routines: WsRegisterObjectClass ( app, "xmlabel", xmLabel ); WsRegisterObjectClass ( app, "xmpushbutton", xmPushButton ); WsRegisterConstructor ( app, "xmRowColumn", XmCreateRowColumn ); WsRegisterCallback ( app, "push", pushCB, NULL ); In environments supporting shareable images, all toolkit classes and constructors may be registered during toolkit initialization. To initiate creation of the widget tree from the definitions stored in the X resource database, an application must (either directly, or by means of a callback) invoke the routine: WsCreateXrmChildren ( widget ); WIDGET TREE CREATION MECHANISM The WsCreateXrmChildren routine scans the X resource database for widget subresources in the following format: path...widget.[un]managed.child_n: name,class[,nonrecursive] For each such subresource, the routine creates a child as specified by the name and object class (or the creation routine - constructor). Creation recursively descends the widget tree, unless stopped by "nonrecursive" option. The latter may be used to defer sub-tree creation, using a callback which invokes WsCreateXrmChildren (for example, WsCreateXrmChildrenCB). When a child is created, WsCreateXrmChildren checks the resource database for xrmCreateCallback resource for the child, and executes such callbacks if present. This mechanism allows the delivery of child's widget ID to other, already existing widgets (such as a Motif defaultButton resource in dialog boxes). CALLBACK STRING CONVERSION A string to callback converter is provided with the package. The converter builds an XtCallbackList using registered callback names. Any callback on the list may have an optional string argument. A pointer to the string is used as callback client data. If no argument (string) is provided, the default client data value provided at registration time is used. The callback resource specification in the X resource database has the following format: path...widget.callbackName: name[(args)][,name[(args)]]... where name is the callback name assigned by WsRegisterCallback, and args presents an arbitrary string. WIDGET TREE CONTROL CALLBACKS The package provides basic callbacks for widget tree control. The callbacks take a (list of) widget names as "client data". The widget name is qualified according to Xrm rules: box.label. The following is list of the provided callbacks: o CreateXrmChildrenCB ( widgetName, widgetname ...) creates children of the named widgets as specified in the X resource database o ManageNamedChildrenCB ( widgetName, widgetName ...) manages a (list of) named widget(s) o UnmanageNamedChildrenCB ( widgetName, widgetName, ... ) unmanages a (list of) named widget(s). o SetWidgetResourceCB ( resourceName, widgetname, ... ) sets the specified resource in a (list of) named widget(s) to the widget id of the widget invoking the callback. Consider the callbacks above as a starting point. More callbacks can be provided to control popup/popdown, to load additional resource files and much more. COMPARISON WITH UIL The X resource database user interface definition, here (for lack of better names) referred to as WsXc, performs essentialy the same function as UIL. A complete comparison with UIL can not be done without additional input. Here I try only to mention several important differences between UIL and WsXc. Implementation: A UIL application uses multiple user interface definition sources (application code, UIL file, compiled UID file and an X resource file). WsXc requires only application code and an X resource file, and the application code would be limited to callback functions. The UIL approach is based on a compiler generating intermediate code which is interpreted by Mrm at runtime. WsXc is purely a runtime interpreter. Performance: Since UIL uses pre-compiled, machine specific data, the widget tree creation should be faster than that for WsXc. However, even UIL widget creation accesses the X resource database for resources NOT explicitly specified by the UIL file. Since MOST resources are usually NOT explictly specified, the overhead depends more on the Xrm database volume, than on the widget creation method used. Preliminary experience with WsXc is favorable. However, final judgement requires much more experience than is currently available. Extensibility. Adding new widgets to UIL, even with the new Motif WML facility, is not an easy process. Adding new data types (resource representation types) to UIL is sometimes impossible. On the contarry, there is nothing special about adding additional widgets to WsXc. The same method also applies to adding new data types. The only requirement is the addition of a convertor from string to a particular data type. Syntax Checking: The UIL compiler can perform rigorous syntax checking for widget resources, thus assisting in user interface development. WsXc can not catch any syntax errors in resource pathname specification, such resources are simply ignored. However, errors in resource value specification can be caught by the resource converter. In addition, a simple tool that acquires a widget's resource list and performs X resource file syntax checking can be provided. Value Computations: The UIL compiler can compute the geometry of individual widgets using arbitrary arithmetic expressions. Geometry values in the X resource database can not, currently, contain expressions. But, since Xrm uses cpp, a string substitution could be applied. This limitation is a resource converter issue. A more intelligent string to integer converter could evaluate arithmetic expressions, including X resource database value substitution. Besides, geometry configuration should be left to the geometry manager widgets and not hardcoded. Resource Conversions: UIL supports resource conversions such as colors, pixelmaps and compound strings. Many of the conversions are performed at runtime, using resource converters, the same as WsXc. For some resources, such as Compound Strings, UIL compile time conversion provides some runtime savings. In addition, the current string to compound string resource converters are not intelligent enough to allow an unlimited compound string specification in an X resource file. -- =*= Opinions presented here are solely of my own and not those of Auto-trol =*= Martin Brunecky marbru@auto-trol.COM (303) 252-2499 {...}ncar!ico!auto-trol!marbru Auto-trol Technology Corp. 12500 North Washington St., Denver, CO 80241-2404
nazgul@alphalpha.com (Kee Hinckley) (03/20/90)
In article <777@auto-trol.UUCP> marbru@auto-trol.COM () writes: > definition by replacing UIL. I am posting an overview of this "POOR > MAN'S UIL" here to get some feedback on. If there is enough > interest, I can post the code, which has been tested with Motif and > other widgets on SPARC, Ultrix/RISC and VMS/VAX, on comp.sources.x. ... A couple concerns. 1) The major thing which keeps me from totally dumping UIL is compound string support. In fact however, UIL doesn't even provide the kind of support that I need (how do I use UIL to put up the message: Sorry, there is no mail from John. Where "John" is English and everything else is Farsi?). I think the real solution there is a message-catalog-style UIL interface. Presumbably you could do something like this in the Xresources file using some kind of character encoding for the international strings, and special escape sequences for program input strings, but I don't know how easy it would be, and it probably wouldn't be useful without a program to construct them. This isn't really specific to your UIL replacement of course, just a general concern. 2) Consider the following (somewhat fragmented) XmForm code, how would your solution handle it. /* * The first issue here is that we have massive references to other * widgets. That presumbably can be handled? */ SETARG(XmNtopAttachment, XmATTACH_FORM); SETARG(XmNleftAttachment, XmATTACH_FORM); leftWidget = XmCreateLabelGadget(form, "Name:", args, i); XtManageChild(leftWidget); SETARG(XmNleftAttachment, XmATTACH_WIDGET); SETARG(XmNleftWidget, leftWidget); SETARG(XmNrightAttachment, XmATTACH_FORM); rightWidget = XmCreateForm(form, "name", args, i); XtManageChild(rightWidget); /* ATTACH_OPPOSITE is a misnomer. It actually means ALIGN_EDGES. */ SETARG(XmNtopAttachment, XmATTACH_WIDGET); SETARG(XmNtopWidget, rightWidget); SETARG(XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); SETARG(XmNrightWidget, leftWidget); leftWidget = XmCreateLabelGadget(form, "Address:", args, i); XtManageChild(leftWidget); /* * The second issue is with convenience routines which create widgets * behind your back. Note here that the widget pointer I have to use * to set the constraint resources is a hidden parent of ScrollText. * * By the by. Does anyone know how this works in UIL? I haven't tested * it yet. My guess is that it either doesn't work, or is hard-coded into * the UIL code (let's hear it for extensibility!). There is actually * a way to do it without hardcoding - namely you check to see if the * parent of a widget is the same as the parent you gave it, if not you * keep moving up the widget ree until you find the parent pointer, then * use the one just below it. That way works even if the implementation * changes, whereas the code below would probably break. */ SETARG(XmNeditMode, XmMULTI_LINE_EDIT); rightWidget = XmCreateScrolledText(form, "address", args, i); SETARG(XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); SETARG(XmNtopWidget, leftWidget); SETARG(XmNleftAttachment, XmATTACH_WIDGET); SETARG(XmNleftWidget, leftWidget); SETARG(XmNrightAttachment, XmATTACH_FORM); XtSetValues(XtParent(rightWidget), args, i); XtManageChild(rightWidget); Incidentally. OSF did at one point consider using an extended Xresources form as an alternative to UIL, but was convinced (I forget the exact reasons) that it wasn't appropriate (too hacky?). -kee -- +-----------------------------------------------------------------------------+ | Alphalpha Software, Inc. | Voice/Fax: 617/646-7703 | Home: 617/641-3805 | | 148 Scituate St. | Smart fax, dial number. | | | Arlington, MA 02174 | Dumb fax, dial number, | BBS: 617/641-3722 | | nazgul@alphalpha.com | wait for ring, press 3. | 300/1200/2400 baud | +-----------------------------------------------------------------------------+
marbru@auto-trol.UUCP (Martin Brunecky) (03/22/90)
In article <1990Mar19.161533.13651@alphalpha.com> nazgul@alphalpha.com (Kee Hinckley) writes: > In article <777@auto-trol.UUCP> marbru@auto-trol.COM () writes: >> definition by replacing UIL. I am posting an overview of this "POOR >> MAN'S UIL" here to get some feedback. > >1) The major thing which keeps me from totally dumping UIL is compound >string support. In fact however, UIL doesn't even provide the kind of >support that I need ...(text deleted)... Presumbably >you could do something like this in the Xresources file using some kind >of character encoding for the international strings, and special escape >sequences for program input strings, but I don't know how easy it would >be, and it probably wouldn't be useful without a program to construct >them. It can be character encoding, but it can be a message reference as well, where the string in X resource is just a reference to a compound string stored somewhere else, and (presumably) created with a (native language specific) compound string editor. The beauty of X resource converters is that they'r simple, and can be overloaded. Sure, it would be great to have a unified way of defining compound strings in X resource files, but it has to wait till we decide what a compound string is. Since I don't work for an OpenEverything-) company, I'v got to wait rather than set-up s standard. The entire Compound String can of worm is too big to be resolved overnight. And UIL definition has the same problem as any other programming language ( and X resource database ). Unless you assume UIL compilers working with "native" character set, i.e. Chinese editor, Chinese UIL compiler, you will always need some kind of character encoding. > >2) Consider the following (somewhat fragmented) XmForm code, how would >your solution handle it. > >/* > * The first issue here is that we have massive references to other > * widgets. That presumbably can be handled? > */ > ( ... code deleted ... ) > There is no problem defining existing widgets as resources to other widgets - just a string to widget converter. Sorry I did not mention one. The problem is what to do in cases like yours, where resources are not known until all involved widgets are created. For simple cases (such as a default button), I did provide WsSetWidgetResourceCB callback. This callback sets a specified resource of a specified widget to invoking widget's ID. For your case I'd need a more generic one, specifying widget ID to to set. Easy to do. I did not think of one, since to accomplish your task we have WsMatrixBox, which does all you need with 2-3 resources, without all that ugly code. ( AttachedBox is not the best solution to the problem, in fact, I believe it discourages people from using and writing constraint widgets ). >/* > * The second issue is with convenience routines which create widgets > * behind your back. Note here that the widget pointer I have to use > * to set the constraint resources is a hidden parent of ScrollText. I have a very strong opinion about "confusion routines" which create widgets behind your back, but I can't post it here -). With the X resource database, there is no problem, since the "hidden" widget always has a name (somehow constructed by the confusion routine). And since there is a name, and a known place in widget hierarchy, you can define any resources you wish. > >Incidentally. OSF did at one point consider using an extended >Xresources form as an alternative to UIL, but was convinced (I forget >the exact reasons) that it wasn't appropriate (too hacky?). > Wasn't the real reason some OSF member was already using UIL and wanted to make it a "standard" ? -- =*= Opinions presented here are solely of my own and not those of Auto-trol =*= Martin Brunecky marbru@auto-trol.COM (303) 252-2499 {...}ncar!ico!auto-trol!marbru Auto-trol Technology Corp. 12500 North Washington St., Denver, CO 80241-2404
rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (03/22/90)
Sure, it would be great to have a unified way of defining compound strings in X resource files, but it has to wait till we decide what a compound string is. Try the MIT X Consortium's Compound Text standard.