|resources:||Home Mailing List Installation Usage Developer Overview (Beta) Developer Case Study (Beta) Source Code Members Bugs Screenshots|
Development Case Study
- The Interface
This document will deconstruct a simple interface panel and business logic for the PDB2PQR service.
...For 1.0.2 The PDB2PQR service is releated to the APBS application; it's purpose is to convert a PDB formatted molecule into the PQR format required by APBS. This particular example was chosen because it is relativley simple to create yet makes comprehensive use of Gemstone's functionality.
Usage of PDB2PQR is straightforward:
- The user selects a single input file, a PDB, either by dragging it over from the Gemstone Filesystem view or by clicking the "Select PDB..." button
- Parameters are chosen via a menu and several checkboxes
- The user clicks the "Run" button
- When complete, focus transfers to the "Output" tab which displays any output generated
- Output is viewed by clicking it's "Open..." button and can be saved to the local desktop either by dragging the "Save..." button over to the Filesystem view or by clicking it.
Before starting make sure that you're familiar with general usage and the developer overview. The actual backend Opal Web service will not be discussed in any detail here but there is full documentation available: http://nbcr.net/services/opal/.
There are over 100 XUL widgets (see the list) available to use when designing an interface, not including HTML elements which can also be used. The next few sections only cover usage of a few key widgets as they relate to the PDB2PQR interface. For a comprehensive introduction, visit XULPlanet's tutorial: http://www.xulplanet.com/tutorials/xultu/
The simplest kind of boxes are the vbox and the hbox which orient their children vertically and horizontally respectively. Vboxes and hboxes are only used for organization of other elements and don't display content of their own--that is, a vbox without any children will not display anything on the screen. These boxes can hold nearly any type of child content; on lns 36 and 98, vboxes are used to group a large number of elements together into related sub-panels. Liberal use of these
Specialized boxes have a specific function or method of laying out content. Some examples used in the PDB2PQR panel include tabs, groupboxes and grids.
When the panel has just been opened the service hasn't been run and there is no output yet to display, but we want to keep an output placeholder ready for when there is some. In order to reduce interface clutter we can put the output container into a tab element which will be hidden until it's needed. The user can then click back and forth between the Input and Output tabs and see only the part they want. XUL tabpanels are contained in a tabbox (ln 28).
The Input panel is further subdivided into two groupboxes named "Run" and "Input", (lns 37 and 61). Groupboxs are often used to visually distinguish a group of related elements. An optional caption can be used to further distinguish the group. Grid elements, the XUL equivelent of HTML tables, are commonly paired with groupboxes to lay out elements in an orderly row/column fashion. Check here for additional explanation and examples of grid usage.
In most cases the layout
engine does a good job of positioning, sizing and ordering XUL elements efficiently on the page.
If desired though, the developer can alter the look of an element either with CSS or individually
Some of the boxes in PDB2PQR use
flex attribute to tell the layout engine to
make the element "greedy" and take up additional space on the page if it exists. The effect is that
elements with higher
flex numbers expand faster than elements.
The next two sections will discuss in more detail how the Run and Input panels were designed.
Once the run button is clicked, a special XUL widget called the progressmeter can be used to keep track of the job's duration. Every time the service returns status, another function is called to update a status message in the textbox on ln 54.
The purpose of this panel is to provide users means of selectiong various options for the Web service. Of the four options, two are "switches" (debumping, hydrogen optimization) meaning that the option is either present or not, one requires a choice between several options (forcefield), and one requires direct user input (Propka).
(ln 90) is used to get text input from
the user. Notice that this textbox has the attribute
hidden set to true; hidding the box helps make the interface
hidden attribute based on whether the checkbox on ln
75 is checked.
The first event to happen though is that ithe
init() function gets called when the XUL is
init() takes the service endpoint from the Gemstone created
selfInfo variable and displays it at the top of the page to let the user know that the panel is
ready for use.
Only two of the options in the Input panel require immediate handling: "Select PDB" needs a function to "get" a file, and "..PROPKA" needs a function to reveal the hidden textbox.
"...PROPKA" is simple to handle. When the checkbox on ln
75 is checked,
either sets or removes the
hidden attribute on the
ph_val textbox and its label.
When clicked, "Select PDB" calls
path. The reason
is that this same function is also to recieve data when the user drags a PDB to the panel rather than clicking the
functions can take a variable number of arguments, named or not. Instead of naming arguments as in the example, a special
local variable can be used to gain access. In this particular case the function just ignores the
arguments if they don't exist and assumes that we want the user to browse their system for a file;
is the Gemstone API function that does the work to open up that file browsing dialog. Once selected, the file's
name is set into the
pdb-text textbox to show the user that they were sucessful.
Drag and Drop for the entire Input box is enabled on ln
61 in conjunction with the
broadcaster element on ln
19. A broadcaster is used
"when you want multiple elements to share one or more attribute values, or when you want elements to respond to a state change".
So rather than typing the
ondragdrop attributes in multiple places we can
When a file is dragged over the panel,
dropObserver.onDragOver is checked to make sure
that the action is allowable. Only one action, dropping a file on a textbox is disallowed in this case.
Once the file is finally dropped
selectPdb() is called with its path as an argument.
Output for the PDB2PQR Web service is a series of links pointing to the converted file, the original input,
and a file containing any error information. The function
this output and dynamically creates XUL for the user to download or view the files.
First, the output SOAP message (specified by Opal) is converted to a DOM structure. This DOM structure can be used to do an XPath query as on ln 175 which searches for all occurences of a file type (stdErr, stdOut, outputFile). For each result of this query a row is added to the Output panel which contains two buttons: "Open..." opens a browser window to view the file, "Save..." opens a Filepicker to save the file. The lines:
btn2.setAttribute( "v" , url );
btn2.setAttribute( "ondraggesture", "nsDragAndDrop.startDrag(event,outputFileObserver);" );
1) set the file's URL as an attribute of the button capable of being dragged 2) make the button
drag-aware. When dragged the
outputFileObserver takes the special attribute and
and starts the drag & drop transfer.
run() function accomplishes several things:
- resets the Input and Output panels: this prevents confusion in case users run multiple jobs in the same panel
creates an input SOAP message: the
createInput()function "scrapes" the interface for parameters and constructs the input message according to the Opal WSDL and PDB2PQR's metadata.
sets up a Job object: adds callbacks to listen to the job's lifecycle events
- launches the Job: (optionally) adds the Job object to the Job Manager and launches it
- disables further user input: since it might take a moment for the Web service to respond, this prevents the user from accidentally launching the same job multiple times
Although the implementation varys, these same five steps are repeated for nearly every service/panel combination.
Steps 2 and 3 are particulary important. PDB2PQR does not require many parameters to run and therefore does not require any complex interface design; a more complex service/interface might choose to keep an internal hash of input parameters rather than using the "screen scrape" method used here.
responseHandler() function used for step 3 is used as the callback for every job lifecycle
event. Each event leads to a status update except for "onjobcompletion" which leads to the Output sequence