[R-gui] Re: XML specifs for R GUIs dialog boxes

Duncan Temple Lang duncan@research.bell-labs.com
Tue, 26 Nov 2002 16:32:12 -0500


And also, Glad, Gtk's interactive GUI developer also has an XML format
that it uses. It is definitely useful, nay essential, to avoid
inventing a different version of something that exists. Deploying
standards from other domains is vital for us in statistics.

 D.

Warnes, Gregory R wrote:
> 
> A couple of ideas from the peanut gallery:
> 
> Why not use HTML forms syntax when this is possible?  This would make things
> simpler for folks who already know HTML.
> 
> Alternatively,
> 
> Has anyone taken a look at XForms specification that the W3C has been
> working on?  Since they have been working on a general method for handling
> forms, we may be able to borrow some of what they have done.
> 
> -Greg
> 
> > -----Original Message-----
> > From: thomas.friedrichsmeier@ruhr-uni-bochum.de
> > [mailto:thomas.friedrichsmeier@ruhr-uni-bochum.de]
> > Sent: Tuesday, November 26, 2002 1:08 PM
> > To: r-sig-gui@stat.math.ethz.ch
> > Subject: [R-gui] Re: XML specifs for R GUIs dialog boxes
> > 
> > 
> > > - Since someone must initiate a document for the specifs, and Thomas
> > > seems to have something almost ready, I proposed him to 
> > make a draft.
> > > At this stage, modifications in a document will be more constructive
> > > than loosy discussions in R-SIG-GUI.
> > 
> > Ok, here's a rough draft. Note, that it is written from my subjective 
> > point of view, of what is needed and how it should be done. I'm 
> > picking up a few points raised in the discussion so far, but I'm 
> > simply ignoring others. This draft should therefore only serve as an 
> > aid in discussion.
> > 
> > I call it "specification of a plugin-description language for R-
> > frontends". "Plugin" refers to the fact, that the modules should be 
> > easy to insert into any R-frontend, preferrably but not necessarily 
> > without recompilation, but in any case without changes to the 
> > application-code. "R-frontends", because I'm currently only 
> > considering R. Extension to multiple backends (MatLab etc.) will 
> > require providing multiple variants of the "code"- and "result"-
> > sections (see below).
> > 
> > First of all, a few general considerations:
> > - The specification should be useful both of the general approaches 
> > "extend R to have a GUI" and "build a GUI around R". It should make 
> > as little assumptions as possible on what data is stored where, how 
> > exactly it is passed to and from the backend etc.
> > - It should be useful even to applications implementing only a 
> > limited subset of functionality, i.e. make as little assumptions as 
> > possible on what the application can interpret. Where advanced 
> > specifications are allowed, these should be designed to be truely 
> > optional, i.e. the plugin should still be useful, if those 
> > specifications are not handled by an application (though they may be 
> > used to enhance the functionality for applications that can handle 
> > them).
> > - It should focus on describing core-functionality like "for a 
> > correlation you need at least two numeric vectors, and you can use 
> > these options". It should try to leave most fancy additional stuff to 
> > the application. It will however not be limited to describing core-
> > functionality.
> > - In general, the particular application using the plugin should be 
> > free to provide it's own consistent look and feel. That is, the major 
> > goal is not to provide a similar look-and-feel of a certain plugin 
> > across different applications using it, but rather consistency across 
> > different plugins used in the same application. Therefore, the 
> > specification will not be tailored towards allowing easy control of 
> > the exact look of a dialog.
> > - In particular the specification should not make any specific 
> > assumptions on how e.g. context-help is invoked on a widget (right-
> > click, short-cut, help-button, mouse-over...) or on how values can be 
> > entered (pasting, drag-and-drop, selection only vs. allowing manual 
> > editing, handwritten input via a stylus...).
> > - Recurring tasks (such as selecting a vector/variable) should be 
> > handled by standard "widgets" whereever possible, custom solutions 
> > should only be used, when there is no good way to solve a problem 
> > using only the standard widgets. See above.
> > - The specification will not describe the entire GUI of a plugin. The 
> > application will take care of providing standard-elements such as a 
> > "help"-button, "close"/"submit" and anything it thinks might be a 
> > good idea. The specification may however give a hint, if some of 
> > these standard-elements are not needed (not described below, yet).
> > 
> > General structure:
> > - The specification is written in an XML-variant.
> > - It is divided into five or six main sections, which will be 
> > described in more detail below:
> > a) a section "location", which describes, where the plugin logically 
> > belongs (e.g. in a menu-structure), and what it should be called.
> > b) a section "layout" describing wich widgets are used, and how they 
> > should (preferrably) be placed, labeled etc.
> > c) a section "code" describing how the values entered into the 
> > widgets should be used, i.e. what the resulting R-command should be
> > d) a section "help" providing a use-centered help on the plugin
> > e) a section "output" describing, how the output should be handled, 
> > e.g. what sort of information will be provided in R-output and how it 
> > can be parsed.
> > f) potentially a section "dynamics" providing the ability to 
> > dynamically change things in the GUI (something like events).
> > 
> > The sections is detail:
> > "location":
> > Only two different tags are allowed in this section: further 
> > "location"-tags and "entry"-tags. "location" describes a (new) level 
> > in the hierarchy (e.g. a sub-menu), "entry" marks the end-point, 
> > where the plugin will finally be placed (e.g. a menu-entry). The 
> > structure is strictly hierarchical, but it is allowed to specify 
> > multiple "locations" for a plugin:
> > 
> > 	<location>
> > 		<location id="first_menu" label="Analysis">
> > 			<location id="x_tests" label="Fictional Tests">
> > 				<entry id="my_test" label="Some 
> > purely fictional test"/>
> > 			</location>
> > 			<location id="y_tests" label="Absurd Tests">
> > 				<entry id="my_test" label="Some 
> > purely fictional test"/>
> > 			</location>
> > 		</location>
> > 		<location id="extras" label="Extras">
> > 			<entry id="my_test" label="Some purely 
> > fictional test"/>
> > 		</location>
> > 	</location>
> > 
> > The location-tag takes the following attributes:
> > id: An internal identifier, that will be used to identify a point at 
> > a certain level in the hierarchy. E.g. if we have two plugins, both 
> > specifying "first_menu" as the id of the top-level location, this 
> > means, they will both be placed under that branch of the hierachy. If 
> > a certain id does not yet exist at a certain level in the hierarchy, 
> > the application will create that and label it:
> > label: The label for this branch of the hierarchy. Will only be used 
> > for the first plugin encountered that creates this branch.
> > The entry-tag takes the same attributes:
> > id: It two entries at the same level in the hierarchy exist, the one 
> > encountered later will overwrite the first (this will make it 
> > possible for the user to load an enhanced or own-created plugin, that 
> > will be used instead of the standard-plugin for the same function).
> > label: The label to be used.
> > 
> > In the above example, the plugin is placed in three different places:
> > Analysis->Fictional Tests->Some purely fictional test
> > Analysis->Absurd Tests->Some purely fictional test
> > Extras->Some purely fictional test
> > 
> > Generally it is however desirable to use only a single unique place 
> > per plugin.
> > 
> > 
> > "layout": It probably not the right term, since it also describes a 
> > lot of the functionality. In general this section is about creating 
> > and placing widgets. It allows two types of tags:
> > a) tags used for arranging the widgets: "row", "column", "tabwidget" 
> > and "tab"
> > b) tags describing widgets (both "active" and "passive"/decorational 
> > ones). To be detailed below.
> > 
> > ad a):
> > - The "row"-tag signals, that all widgets or layouts enclosed in it 
> > should be placed next to each other horizontally (from left to right)
> > - Similarily widgets/layouts in a "column" will be arranged 
> > vertically.
> > - Both tag take the attributes "width" and "height". These take 
> > integer-values that are interpreted as percent of the space available 
> > in the parent layout (or dialog), e.g.
> > 	<row width="100">
> > 		<column width="30">
> > 			...
> > 		</column>
> > 		<column width="70">
> > 			...
> > 		</column>
> > 	<row>
> > "width" and "height" are only hints to the layouting engine, and may 
> > not be taken literally.
> > [alternative approach: use something more similar to <table>, <tr>, 
> > <td> in HTML, allowing "colspan" and "rowspan" as attributes]
> > 
> > - The <tabwidget>-tag takes as child elements <tab>-tags. Generally 
> > only one <tab> will be visible to the user at a time, and the 
> > <tabwidget> provides a way to switch between the tabs (this will not 
> > necessarily have to be real "tabs", the <tabwidget> might also 
> > provide buttons for the different tabs, with the tabs opening up in 
> > additional windows). <tab>/<tabwidget> should only be used, when 
> > there are a _lot_ of options not commonly used, that can not sensibly 
> > be shown all at the same time. The <tabwidget> does not need to 
> > occupy the whole dialog, i.e. does not have to be at the top-level. 
> > If it is not at the top-level, it takes the "width" and "height"-
> > hints just like any other widget (see below).
> > 
> > ad b):
> > The following widgets are allowed. All widgets allow "width" and 
> > "height"-hints as described above:
> > 
> > "passive" widgets:
> > 
> > <text [wordwarp="boolean"]>Text to be displayed</text>:
> > A simple text/label. "wordwrap" specifies, whether the text is 
> > wrapped automatically as required. A subtag <br/> is allowed for 
> > manual breaks.
> > 
> > <frame><potentially furhter widgets/layouts></frame>
> > If there are widgets/layouts enclosed in the frame-tag, the frame 
> > will be shown as a rectangle with those widgets insides it. If not, 
> > it will be shown as a line (vertical in rows, horizontal in columns).
> > 
> > "active" widgets:
> > Mostly all active widgets _require_ a unique id="string"-attribute 
> > used to identify them. All allow a label="string"-attribute (some 
> > require one), that describes a simple label directly attached to the 
> > widget. Further, all widgets allow a sub-tag 
> > <contexthelp>Description</contexthelp> that describes context-help 
> > that can be shown for this widget (in whatever way).
> > 
> > - option-widgets:
> > 
> > <radio [columnheight="integer"]></radio>:
> > A group of radio-buttons. All <option> tags enclosed are radio-
> > exclusive. Columnheight describes, how many <option>s should be 
> > placed below each other, before starting a new row of buttons. The 
> > <radio> automatically comes with a "frame" or something similar 
> > indicating that the options belong together, so there is no need, to 
> > place the <radio> inside a <frame>.
> > <option value="string" label="string" [checked="bool"]/>:
> > Represents a single option in a <radio>. Use checked="true" to 
> > specify that this button should be selected at start-up. Of course, 
> > only one may be set to "checked". "label" is the text shown next to 
> > the option. "value" is what becomes the value of the radio, if this 
> > option is checked. It is a string value, but of course that string 
> > may also be the string representation of a number. The <option>-tag 
> > does not need an "id", since it belongs to the <radio>, that already 
> > has an id. Of course it may have a <contexthelp> however.
> > 
> > <checkbutton label="string" value="string" [checked="bool"]/>:
> > Mostly like a radio-option, except that it is not contained in a 
> > group, since all buttons may be checked individually. That also 
> > means, that the button requires the id-attribute!
> > 
> > <select selectable="integer"></select>:
> > A string selector. "selectable" specifies, how many options may be 
> > selected simultaniously (0 for all). Takes as sub-tags the <option>s 
> > as described for the <radio>.
> > 
> > Alternative (and probably better) approach to the above three 
> > widgets:
> > <optionselector selectable="integer" 
> > [typehint="buttons|list"]/><option>s</optionselector>
> > This would have the advantages, that a) the application would not 
> > have to be able to provide e.g. buttons, since a "list" can serve the 
> > same functionality. Also, the application could decide on it's own, 
> > what type of widget might be appropriate, e.g. buttons for less that 
> > 6 options (radiobuttons, if selectable="1"), list for more. b) It 
> > would be more abstract, and that'd make it easier to e.g. use options 
> > generated from an R-object.
> > 
> > - object-selection-widgets:
> > 
> > <varselector [offertype="string+string...;string..."]/>
> > A widget, that presents a complete (preferrably hierarchical) list of 
> > all R-objects available. If "offertype" is specified, only objects of 
> > the given type(s) (e.g. numeric+vector) are offered (of course 
> > container-objects like lists and frames will always be shown). The 
> > "+" signals, that both conditions are required for an object to be 
> > acceptable. The ";" represents an OR.
> > 
> > <varslot source="string" type="string+string...;string..." 
> > min="integer" max="integer"/>
> > Holds at least "min", at most "max" variables (-1 for no limit). The 
> > widget will likely look different, depending on whether it can only 
> > hold a single or multiple objects. Since there may be more than one 
> > <varselector> in a dialog, "source" holds the "id" of the varselector 
> > that can be used as a source (of course you can still enter values 
> > manually). "type" specifies a list of acceptable object-types (see 
> > above).
> > Note: The varslot is the only widget, that might potentially hold 
> > "invalid" entries. The application will have to check, whether the 
> > varslot is valid!
> > 
> > <interaction sources="string;string;string"/>:
> > Used for selecting interactions. "sources" is a ";" separated list of 
> > <varslot>s that hold the objects, between which interactions may 
> > occur.
> > 
> > <input type="string" 
> > [typehint="slider|lineedit|textfield|dial|spinbox..."]/>:
> > Takes a discrete value as input (either numeric or string ("type")). 
> > "typehint" suggest, what sort of widget should be used - the 
> > application may decide to ignore that hint if e.g. it does not 
> > support that widgettype.
> > 
> > - output-widgets:
> > 
> > <graph/>:
> > For interactive graphs. The output section will have to describe, 
> > when and how to display something in this widget. Keep in mind, that 
> > some applications might chose to display <graph>s outside the dialog 
> > itself in a separate window, so make sure, the layout remains 
> > acceptable in this case. Ambitious applications will likely provide 
> > means to zoom/rotate/scale the graph, but this will not be detailed 
> > in the plugin-specification.
> > 
> > 
> > "code"-section:
> > approach a):
> > 	<code>
> > 		t.test ($x$, $y$, "$hypothesis$")
> > 	</code>
> > Everything between $-signs is interpreted as the id of a widget. It 
> > will be replaced with the value of that widget.
> > approach b):
> > 	<code>
> > 		t.test (<?php echo "$x, $y, \"$hypothesis\""; ?>)
> > 	</code>
> > Of course in the example nothing is won, but using some scripting-
> > language like PHP may come in handy for complex code.
> > 
> > Either way, besides providing values for $x$, $y$..., the application 
> > should also be able to fill in the following:
> > $x.valid$: boolean, whether the widget hold a valid entry
> > $x.filled$: boolean, whether the widget holds something
> > $x.type$: string, what type of data the widget holds
> > $x.name$: string, the name of the object with escaped quotes, so it 
> > can be used inside e.g. print ("$x.name$")
> > $x.label$: string, some applications may want to provide a more 
> > lengthy description for an object. Applications that don't, will 
> > place an empty string.
> > $x.count$: integer, if more than one object/option may be selected, 
> > returns how many are selected.
> > 
> > 
> > "help"-section:
> > No real ideas on this, yet. plain HTML-body? Include something 
> > generated from the context-help?
> > 
> > 
> > "output"-section:
> > A very vague idea:
> > 	<output>
> > 		<returns>
> > 			<value name="string" [label="string"] 
> > type="string" 
> > description="string"/>
> > 			...
> > 		</returns>
> > 		<parse>
> > 			<?php /* parse output into separate 
> > variables if necessary. Those 
> > variables are described
> > 					above in the 
> > <returns>-section. */ ?>
> > 		</parse>
> > 		<show>
> > 			<?php /* generate an HTML-version of 
> > what the output might look 
> > like. This only generates a
> > 					suggestion. The app may 
> > decide to do it's own formatting. */ ?>
> > 		</show>
> > 	</output>
> > 
> > 
> > "dynamics"-section:
> > An even more vague idea:
> > 	<dynamics>
> > 		<on event="x.changed" do="y.update"/>
> > 		<on event="x.changed" do="z.changeTo(x.valid)"/>
> > 	</dynamics>
> > Here we're really getting into complicated stuff. I propose to use 
> > only one type of event:
> > 
> > .changed : When the value of a widget was changed
> > 
> > And a limited number of functions:
> > 
> > .update : make the widget check, whether it is still valid, or re-
> > read it's 
> > contents (esp. useful for the <graph>-widget
> > .changeTo (newValue) : (newValue passed as string, but may represent 
> > a number)
> > .setEnabled (boolean) : en-/disable widget
> > .changeProperty (property, newValue) : a very powerful function, 
> > allowing to change the attributes of a widget dynamically. Will 
> > likely not work in many apps (or not soon, at least).
> > 
> > _______________________________________________
> > R-SIG-GUI mailing list
> > R-SIG-GUI@stat.math.ethz.ch
> > http://www.stat.math.ethz.ch/mailman/listinfo/r-sig-gui
> > 
> 
> 
> LEGAL NOTICE
> Unless expressly stated otherwise, this message is confidential and may be privileged. It is intended for the addressee(s) only. Access to this E-mail by anyone else is unauthorized. If you are not an addressee, any disclosure or copying of the contents of this E-mail or any action taken (or not taken) in reliance on it is unauthorized and may be unlawful. If you are not an addressee, please inform the sender immediately.
> 
> _______________________________________________
> R-SIG-GUI mailing list
> R-SIG-GUI@stat.math.ethz.ch
> http://www.stat.math.ethz.ch/mailman/listinfo/r-sig-gui

-- 
_______________________________________________________________

Duncan Temple Lang                duncan@research.bell-labs.com
Bell Labs, Lucent Technologies    office: (908)582-3217
700 Mountain Avenue, Room 2C-259  fax:    (908)582-3340
Murray Hill, NJ  07974-2070       
         http://cm.bell-labs.com/stat/duncan