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

Warnes, Gregory R gregory_r_warnes@groton.pfizer.com
Tue, 26 Nov 2002 16:27:13 -0500


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.