Chameleon Client Translator Engine
The Chameleon Client Translator engine is the heart of each client environment interfacing with the Chameleon Server side. Once a translator engine have been developed in a specific client environment, it should comply to the Chameleon standard and be able to translate any server side forms or application without modification to the client code.
Typical environments that we have plans for developing clients for include (GTK, QT, Flash, Xcode, Vb2005, Java, ExtJs, HTML, XUL). If you have skills in any of these areas, you may be interested in developing the code for your favorite client enviroment.
The translator engine converts the xml forms and widgets delivered from the server to forms and controls in the specific client environment you have chosen. The client environment must support minimum DOM XML v3 standard which connects directly to the server url and returns a xml document. The client enviroment must support all the controls/widgets defined in the Chameleon XML Format or be able to simulate these controls/widgets by creating its own composite control.
Following are typical function steps in the translation engine:
Initializing the application
First step is to read the local client side configuration file to determine the URL to the server side application. This URL is referred to as the Application URL. This creates a virtual form and widget representation on the server side which is kept syncronised with the application on the client side.
Once this URL has been retrieved, read it into a Dom XML class available in most client development environments to retrieve the initial forms for the application.
chameleon.AppServerUrl = "http://nix/~matz/chameleon/servers/php/sections/crm/chameleon-server.php"
xmldoc.Load(AppServerUrl)
xmlForm = xmldoc.GetElementsByTagName("decks").Item(0)
sessionId = xmlForm.attributes.GetNamedItem("sid").Value
Typical example of xml returned:
<?xml version="1.0"?>
<decks sid="5b08dd536aa2cd879974daafc59d716f" type="decks">
<window id="crmlist_window" type="window" width="100%" height="100%" label="" formtype="normal">
<menubar xml:id="sample-menubar" type="menubar" parentid="crmlist_window" dock="top">
<menu name="" id="file-menu" type="menu" parentid="sample-menubar" caption="File">
<menupopup xml:id="file-popup" name="" id="file-popup" type="menupopup" parentid="file-menu">
<menuitem id="crmlist_window-100" type="menuitem" parentid="file-popup" caption="New"/>
<menuitem id="crmlist_window-101" type="menuitem" parentid="file-popup" caption="Open"/>
<menuitem id="crmlist_window-102" type="menuitem" parentid="file-popup" caption="Save"/>
<menuseparator id="crmlist_window-103" type="menuseparator" parentid="file-popup"/>
<menuitem id="crmlist_window-104" type="menuitem" parentid="file-popup" caption="Exit"/>
</menupopup>
</menu>
<menu xml:id="edit-menu" name="" id="edit-menu" type="menu" parentid="sample-menubar" caption="Edit">
<menupopup xml:id="edit-popup" name="" id="edit-popup" type="menupopup" parentid="edit-menu">
<menuitem id="crmlist_window-105" type="menuitem" parentid="edit-popup" caption="Undo"/>
<menuitem id="crmlist_window-106" type="menuitem" parentid="edit-popup" caption="Redo"/>
</menupopup>
</menu>
</menubar>
<toolbox id="crmlist_window-107" type="toolbox" parentid="crmlist_window" direction="horizontal">
<toolbar xml:id="nav-toolbar" name="" id="nav-toolbar" type="toolbar" parentid="crmlist_window-107">
<toolbarbutton id="crmlist_window-108" type="toolbarbutton" parentid="nav-toolbar" caption="Companies" event="onclick" />
<toolbarbutton id="crmlist_window-109" type="toolbarbutton" parentid="nav-toolbar" caption="People" event="onclick" />
</toolbar>
<toolbar xml:id="nav-toolbar2" name="" id="nav-toolbar2" type="toolbar" parentid="crmlist_window-107">
<toolbarbutton id="crmlist_window-110" type="toolbarbutton" parentid="nav-toolbar2" caption="Reports" event="onclick" />
<toolbarbutton id="crmlist_window-111" type="toolbarbutton" parentid="nav-toolbar2" caption="Export" event="onclick"/>
</toolbar>
<menubar xml:id="crmlist_window-112" name="" id="crmlist_window-112" type="menubar" parentid="crmlist_window-107">
<menu xml:id="crmlist_window-113" name="" id="crmlist_window-113" type="menu" parentid="crmlist_window-112" caption="Change">
<menupopup xml:id="crmlist_window-114" name="" id="crmlist_window-114" type="menupopup" parentid="crmlist_window-113">
<menuitem id="crmlist_window-115" type="menuitem" parentid="crmlist_window-114" caption="New"/>
<menuitem id="crmlist_window-116" type="menuitem" parentid="crmlist_window-114" caption="Open"/>
<menuitem id="crmlist_window-117" type="menuitem" parentid="crmlist_window-114" caption="Save"/>
<menuseparator id="crmlist_window-118" type="menuseparator" parentid="crmlist_window-114"/>
<menuitem id="crmlist_window-119" type="menuitem" parentid="crmlist_window-114" caption="Exit"/>
</menupopup>
</menu>
</menubar>
</toolbox>
<vbox id="crmlist_window-120" type="vbox" parentid="crmlist_window" width="100%" height="100%">
<text id="test_text" type="text" parentid="crmlist_window-120" align="left" width="10%" height="5%" caption_align="right" caption="" rows="1"/>
<button id="button12" type="button" parentid="crmlist_window-120" align="left" width="100px" caption="Click me" event="onclick,onlostfocus"/>
<button id="openFormButton" type="button" parentid="crmlist_window-120" align="left" width="100px" caption="Open a new form" event="onclick"/>
<button id="openTreeview" type="button" parentid="crmlist_window-120" align="left" width="100px" caption="Open a treeview form" event="onclick"/>
<tabpane id="test_tabpane" type="tabpane" parentid="crmlist_window-120" width="98%" height="90%" event="click">
<tab id="tab_companies" type="tab" parentid="test_tabpane" styleclass="tab" caption="Companies" width="100%" height="100%" event="onclick">
</tab>
</tabpane>
</vbox>
</window>
</decks>
Loading the Widgets Once the xml form have been loaded into the xml document class, you will typically iterate through each widget and translate the widget tag and attributes to your client enviroments equivalent controls/widgets and their properties.
Loading the Events Each widget in the xml form also defines which events are supported for a particular widget. This is to save unnecessary round trips to the server. These events are specified in the 'event' attribute of each widget. This attribute is a comma-delimited definition of multiple. Your translator engine will need to be able to dynamically attach events to your client environment.
The Chameleon server also supports the concept of client-side event functions. They are designed to minimize round trips to the server when the event is a very simple instruction that the client should be able to do without asking for instructions from the server. There are only a few of these as they demand code changes on the client side. Typical clientside events are 'uploadData' and 'closeForm'. Your client environment must be able to support these. These events are flagged in the 'eventpreload' attribute of each widget.
You should be able to use only one function for all the events attached to controls/widgets in the client environment. The only difference between each event is the widget_id and the event name that is flagged in the function. For example when a button is clicked triggering the onClick event, the Application URL is again retrieved but with a couple of parameters appended to it. See example below:
chameleon.AppServerUrl = "http://nix/~matz/chameleon/servers/php/sections/crm/chameleon-server.php?deckid=crmlist_window&widgetevent=onclick&widgetid=button12" xmldoc.Load(AppServerUrl)
Processing the Events Once the URL has been sent to the server, it processes the event and updates the Chameleon virtual server object. The server side works out the difference between the virtual object Before and After the event and formulates a differential xml document which is returned to the client environment. Below is an example of a differential document returned:
<decks sid="5b08dd536aa2cd879974daafc59d716f" type="decks">
<window xml:id="crmlist_window" id="crmlist_window" parentid="" type="window">
<text xml:id="test_text" caption="whohoo" fieldvalue="Clicked the damn button" parentid="crmlist_window" id="test_text" type="text"/>
</window>
</decks>
Updating the Widgets The UpdateForm function on the client side then iterates through the returned widgets, finds them on the client side form and updates/adds the widget attributes returned from the server.
