SCGUI 2 - XML

Remote GUI Protocol

Updated: 9/3/2002


Philosophy

Latency-friendly

Widgets (clients) don't have to send each keystroke to the server in sub-second turnaround time in order to make data entry smooth. You can reduce transmission to just when the form is finished, or send field contents when a given field is exited (and finer levels may be added in the future). This allows some communications and server-side processing to take place in-between "submits". You can have the browser wait for a response, or simply send the specified information and then continue on without the user even aware that something was sent.

SCGUI gives you a wide range of response options to optimize the interaction between the client and the server. This allows it to be "tuned" to run on a variety of networks, with differing bandwidth and response time delay profiles. It can run on fast networks, or slow networks. (However, it is not optimized for high-speed games. It is mostly intended as a business tool.)

Can Run Over HTTP and Others

Although SCGUI was made with HTTP in mind, it is not limited to HTTP. It could possibly even replace X-Windows, Tk, or the Microsoft Windows protocols.

No Local Programming

There is no application-specific programming logic that has to be loaded and "run" on the client. (The SCGUI browser is not meant to be application-specific).

Applets and JavaScript break into the Pandora's Box of Turing-Complete client-side (browser) execution of content. This creates or increases a boat-load of problems:

  1. Complicates the Browser - browser needs a language interpreter.

  2. Complicates the Protocol - Software writers have to learn a new programming language. SCGUI is not tied to any one programming language. The GUI Browser will not even be able to tell what language is running on the server.

  3. Increases security risks. Most web viruses are spread via client scripts.

Turing-Complete usually means introducing general-purpose IF statements, loops, methods, etc. These make the browser and the browser's environment easier to hack, because it allows the hacker to write and place relatively intelligent "agents" on your machine to snoop around and cause havoc. Client-side scripts/applets also can also cause long waits as the browser has to download the script/applet.

Turing-Complete languages also often need constant updating because new bugs or security holes are always being found. SCGUI avoids being Turing-Complete to avoid or reduce these problems.

Some client-side scripting is probably inevitable for some applications or needs, such as when responsiveness is valued over security for whatever business reason. However, it should be considered only an option when the protocol is designed. In other words, the focus should be on script-free-client applications, with client-side scripts viewed as a bonus instead of a necessity.

Delta-Based Updates

The delta-based nature of SCGUI means that we only have to send what changes. With HTML forms, for example, if you want to change one spot on a page, you usually have to send an entire updated copy of the page. With SCGUI, if you want to put an error message on a page, you only have to send the XML code to place that message. You don't have to re-send the whole page.

Open Standard

There are no restrictions on using the SCGUI standard as long as proper credits and sources are given, and non-standard extensions or alterations are fully documented.

Simple

SCGUI is not the only attempt to define GUI's via XML. However, the other approaches I saw were unnecessarily complex and/or trying too hard to be everything to everyone instead of focusing on typical custom business applications. (Also, many did not manage latency and event communication in an HTTP-friendly way, in my opinion.)

Another thing to notice is that almost every operation can be represented with these four elements:

    The Fab Four

  1. Form ID
  2. Widget ID     (leave blank for form attributes)
  3. Attribute Name
  4. The Value
This not only makes things conceptually simple, but also makes it easier to trace and log GUI interaction, create simple list-based scripts, etc. There is no complicated object tree to learn and navigate.

Other

SCGUI has no built-in "flow control" for widget layouts because it is assumed that the server handles such. The server can convert flow layouts into coordinates, which is what SCGUI uses. This keeps the client (browser) simple and stable. Future versions will be able to return the width of the client screen (or view area) so that server-based screen managers can scale stuff as needed for a particular client.

The forest-view philosophy of SCGUI is to have as much of the processing take place on the server as possible, but without significantly affecting or slowing the user experience regardless of network protocols or network speed being used. SCGUI puts into a protocol what it needs and only what it needs to achieve this. It is a tricky balancing act, but SCGUI is up to the task.

See Also: SCGUI History



SCGUI - Draft Specification 2.02j

Event Types
-----------

"none"  - Don't send anything to server upon given event.

"event" - Send only the fact that given widget had
          an event.

"self" -  Send content of self

"group" - Send the contents of all members belonging
          to the same group of the triggered item.
          (For future use only)

"widgets" - Send event and the content of all user-editable
          widgets, but not grid cell contents (or any
          other multi-item widget, such as tree browsers).

"all"   - Send event and content of all user-editable widgets,
          including any/all grid or grid-like contents.
          (Contrast with "widgets" event.)

"close" - Close form of given widget. This is the
          only "local" event defined in SCGUI, except
          for maybe changing form focus (see footnote).


Note that the server can still request values not automatically
sent.


TAGS
----

  wait=<[yes,no]>

Choose between synchronous and asynchronous response mode.
In synchronous mode (wait=yes), no input is accepted until
the server responds to given event. An hour glass or some
other notice is displayed until server response. In
asynchronous mode (wait=no) the given event is put into a
queue and user input is still accepted. This is a key concept.
(Buttons default to WAIT=yes. All others default to
WAIT=no.)

Note that if you need to control waiting at event level instead
of the widget level, then events (below) can optionally
include "wait" and "nowait" sub-tags.
Example: OnPick="event,nowait" or even OnPick="nowait".


  onPick=<event[,wait,nowait]>

For buttons this would be equivalent to a "onClick" event.
For text boxes or grid cells this is equivalent to a double-click.
Note that it is entirely up to the server to do something
with this information. The client simply sends a message
that the event happened (and may wait depending
on the "wait" setting).

  onHop=<event[,wait,nowait]>

Event control when user leaves a control. Similar
to "onBlur" in JavaScript.

  onChange=<event[,wait,nowait]>

[reserved]

  onFocus=<event[,wait,nowait]>

[reserved]

  X=<value>

  Y=<value>

X and Y pixel coordinate of control or form. If a form, then
coordinates are relative to upper left screen corner. If a
form control, then coordinates are relative to containing form.

  Z=<value>

To control Z-order in cases of overlapping widgets. (Use
"visible" instead to bring a form in front.)

  widgetType=<[textbox,button,grid,list,combo,
    checkbox,label,password,menu...]>

Widget type. For "list" widget, list contents are
separated with commas. The biggest difference between a
list and a combo is that a list will return the
ordinal position number of the selected item, while
a combo returns the actual selection value. This is because
combo allows users to type in a value not on the list.
Both default to the first item in the list. Example
list assignment: content="{Canada}{France}{Singapore}{USA}".

For menus the braces syntax is used for nesting.
For example: content="{file {save}{save as {text}{*html}}
{exit}}{view {grid}{column}} {help}". The asterisk is used to
gray-out an option. To un-gray it, simply re-send the
section without the asterisk: content="{file {save
as {html}}}". To remove a menu item, use "-" before it.
A "&" before a letter makes it a short-cut key. A
space after "&" means that it is just a regular
ampersand.

  content=<value>

Content of control. For a textbox this is the contents of
the box, and for buttons this is the button description.

  formID=<value>

An alphanumeric identifier for a given form. You can create
(instantiate) a form simply by "mentioning it" (although you
need to set it's visible property before the user sees it.)

  widgetID=<value>

An alphanumeric identifier for a given widget (button,
textbox, etc.) You can create (instantiate) a widget simply
by "mentioning it" (although you need to set it's visible
property before the user sees it.)

  Visible=<[none,read,full]>

"none" means that control or form is not visible. "read"
means that it is visible but not changable. For buttons,
"read" means that it is not clickable (greyed out).

Setting the visible property to "full" in forms brings that
form to the front (if not already there). "read" on forms
can be used to indicate a form is modal but not selected
(at the moment). Perhaps "true" or "yes" should by
synonymous with "full", since people keep accidently
using those.


  Width=<value>

Width in pixels. A default of about 90 is used if not given.

  Height=<value>

Height in pixels. Not all controls recoginize this
(ignoring it).

  Row=<value>

Grid row (cell-wise)

  Col=<value> 

Grid column (cell-wise)

  Rows=<value>

Max grid grows

  Cols=<value>

Max grid columns

  event=<[onPick,onHop, etc....]>

A server-direct message that tells the type of event
that was triggered.

  group=<group name>

Group name for grouping widgets. (For future
use only).

  request=<widget ID>

A client-directed message where the server asks for
the value of a given field (tag), usually the "content"
field.

  command=<command>

A client-directed special command. For example,
"release" releases (de-allocates) the given form.


More to come...


EXAMPLE
-------

   *------------------------------------------*
   |              Enter Password              |
   |------------------------------------------|
   |                                          |
   | Username:  [Bob         ]                |
   |                                          |
   | Password:  [******      ]                |
   |                                          |
   | Save Password:  [X]                      |
   |                                          |
   |          *--------*   *--------*         |
   |          | Cancel |   | Log In |         |
   |          *--------*   *--------*         |
   |                                          |
   *------------------------------------------*

    Character Version
   (This is only a rough approximation.)

screen sample
GUI version

<SCGUI@CLIENT FORMID=formpw CONTENT="Enter Password"/>
<SCGUI@CLIENT FORMID=formpw WIDTH=300 HEIGHT=200/>
<SCGUI@CLIENT FORMID=formpw WIDGETID=label1
  WIDGETTYPE=label X=2 Y=30
  VISIBLE=full CONTENT="Username:" />
<SCGUI@CLIENT FORMID=formpw WIDGETID=label2
  WIDGETTYPE=label X=2 Y=60
  VISIBLE=full CONTENT="Password:" />
<SCGUI@CLIENT FORMID=formpw WIDGETID=label3
  WIDGETTYPE=label X=2 Y=90
  VISIBLE=full CONTENT="Save Password:" />

<SCGUI@CLIENT FORMID=formpw WIDGETID=username 
  WIDGETTYPE=textbox CONTENT="Bob"
  X=130 Y=30 VISIBLE=full
/>
<SCGUI@CLIENT FORMID=formpw WIDGETID=passw
  WIDGETTYPE=password
  X=130 Y=60 VISIBLE=full
/>
<SCGUI@CLIENT FORMID=formpw WIDGETID=keeper
  WIDGETTYPE=checkbox
  X=180 Y=90 VISIBLE=full
  CONTENT="Yes"
/>
<SCGUI@CLIENT FORMID=formpw WIDGETID=cancelbut
  WIDGETTYPE=button
  X=100 Y=140 VISIBLE=full
  CONTENT="Cancel" ONPICK=event
/>
<SCGUI@CLIENT FORMID=formpw WIDGETID=loginbut
  WIDGETTYPE=button
  X=150 Y=140 VISIBLE=full
  CONTENT="Log In" ONPICK=widgets
/>
<SCGUI@CLIENT FORMID=formpw VISIBLE=full/>


TALKING TO SERVER 
-----------------

Example:

User keys in values and presses the "Log In" button:

<SCGUI@SERVER FORMID=formpw WIDGETID=loginbut EVENT=onPick/>
<SCGUI@SERVER FORMID=formpw WIDGETID=username CONTENT="Bob"/>
<SCGUI@SERVER FORMID=formpw WIDGETID=passw CONTENT="foobar"/>
<SCGUI@SERVER FORMID=formpw WIDGETID=keeper CONTENT="Yes"/>

If the button had instead used "ONPICK=event" instead
of "ONPICK=widgets" (above), then only the first line would 
have been sent.

If that was the case, then the server could still request each
value:

<SCGUI@CLIENT REQUEST=Content FORMID=formpw WIDGETID=username />
<SCGUI@CLIENT REQUEST=Content FORMID=formpw WIDGETID=passw    />
<SCGUI@CLIENT REQUEST=Content FORMID=formpw WIDGETID=keeper   />

[end]


An Alternative

Here is an alternative approach based on a format proposed by a friend. It is a bit more in the spirit of traditional XML. I think it would be harder to generate, but perhaps more compact.
<scgui>
  <form id="form1" content="Login Screen Demo" visible="full"
        width=275 height=260>
    <widget type="label" id="label1" x=2 y=30 
        visible="full" content="Username:" />
    <widget type="label" id="label2" x=2 y=60 
        visible="full" content="Password:" />
    <widget type="label" id="label3" x=2 y=95 
        visible="full" content="Save Password:"/>
    <widget type="textbox" id="username" x=130 y=30
        visible="full" content="Bob" />
    <widget type="password" id="passw" x=130 y=60 
        visible="full" content="" />
    <widget type="checkbox" id="keep" x=140 y=90 
        visible="full" content="yes"/>
    <widget type="button" id="cancel" x=40 y=140 
        visible="full" content="Cancel"
        onpick="event" />
    <widget type="button" id="login" x=135 y=140 
        visible="full" content="Log In"
        onpick="widgets" />
  </form>
</scgui>
Note that "form" may conflict or cause confusion with HTML's "form". Perhaps "SCGUIform" instead?


Footnotes


SCGUI Main | Contact