August 15th, 2007 · 1 Comment
This is a short by-no-means-exhaustive list of freely available OpenLaszlo source code, for all those out there who like to steal learn from other people’s work.
OpenLaszlo “official” demos
Here you will find a range of interactive demos showing some of what OpenLaszlo makes possible.
www
OpenLaszlo Incubator Project
The Incubator directory contains components and other code that have been contributed to the OpenLaszlo project, but have not yet been fully integrated into the product.
src
Applejuice
Applejuice is a free web-based photo gallery. Its user interface is simple and uncluttered, to give your photos center stage.
www
Our First iPhone App
www - src
OpenLaszlo YouTube Player Demo and Source Code
www
Open Source SimFaux OpenLaszlo Code Now Available via Subversion
SimFaux is an interactive TV station simulator written in OpenLaszlo, by Don Hopkins, for the HuffingtonPost Contagious Festival.
www
Source code for Zoom Maps project (Openlaszlo)
www - src
Laszlo: An Open Source Framework for Rich Internet Applications
www
blogbox
Blogboxes provide exciting, instantly deployed functionality for your blog or Web site.
www
Glancer: Friend finder and Scheduler application
www - src
Tags: OpenLaszlo
This is a brief overview of how I initialise context menus in my OpenLaszlo application. There is nothing magic here, it is all in the documentation, but I hope this will save someone the time it took me to pull it all together.
CREATING THE CONTEXT MENU
This handler creates an empty context menu for the current object. A delegate is declared. The delegate will be called when the context menu is invoked, and is responsible for initialising the context menu. I use a delegate because the context menu depends on the application state.
<handler name="oninit">
var cm = new LzContextMenu();
cm.setDelegate(new LzDelegate(this, 'init_cm'));
this.setContextMenu(cm);
</handler>
INITIALISING THE CONTEXT MENU
This is the method that will be invoked to initialise the context menu.
The wrinkle in my application is that there is a ‘global’ context menu that is accessed by right-clicking anywhere, as well as a more object-specific context menu when a visual object is clicked. The specific context menu includes the global menu items as well. So this method first calls the method that initialises the global context menu (to make sure the global context menu is in the right state), then at the end of the method the menu items from the global context menu are copied into this context menu.
Otherwise this method is fairly straightforward. hideBuiltInItems() removes Flash-installed default menu items (but not all of them BTW). clearItems() removes all custom items from the context menu.
<method name="init_cm">
<![CDATA[
cm_util.init_cm(); // init global menu
var cm = this.getContextMenu();
cm.hideBuiltInItems();
cm.clearItems();
var item;
item = cm.makeMenuItem('label1',
new LzDelegate(xxx, 'yyy'));
item.value = parent;
cm.addItem(item); if (...)
{
if (...)
{
item = cm.makeMenuItem('label2',
new LzDelegate(zzz, 'aaa'));
}
else
{
item = cm.makeMenuItem('label3', null);
item.setEnabled(false);
}
cm.addItem(item);
}
if (...)
{
if (...)
{
item = cm.makeMenuItem('label4',
new LzDelegate(bbb, 'ccc'));
item.value = this;
item.setSeparatorBefore(true);
cm.addItem(item);
}
else
{
if (...)
{
item = cm.makeMenuItem('label5',
new LzDelegate(ddd, 'eee'));
item.value = this;
}
else
{
item = cm.makeMenuItem('label6', null);
item.setEnabled(false);
}
item.setSeparatorBefore(true);
cm.addItem(item);
}
}
// load global menu
var gcm = canvas.getContextMenu();
var gitems = gcm.getItems();
var glen = gitems.length;
for (var i = 0; i < glen; i++)
{
if (i == 0)
gitems[i].setSeparatorBefore(true);
cm.addItem(gitems[i]);
}
]]>
</method>
THE METHOD
This is an example of the methods invoked by clicking an item in the context menu. This example uses the ‘value’ parameter which can be set when creating the menu item, as is done is some of the menu items above.
<method name="eee" args="item">
return fff(item.value);
</method>
BUGS
From the documentation:
There is an unresolved bug with nesting of context menus in views that were not direct children of the canvas which seems to happen in Flash 7, but is not present when you compile for Flash 8 target (lzr=swf8). That is, in the Flash 7 runtime, you cannot put a menu on a view unless its immediate parent is the canvas.
RESOURCES
“View Source” right click menu item
OpenLaszlo: a way to propagate context menus
Tags: OpenLaszlo
I have been playing around with the initstage property on views, in order to enhance performance (references below). The initstage property tells OpenLaszlo when to complete initialisation after the object has been instantiated.
The Manual
initstage
The execution of a node’s init method and sending of the oninit event is under the control of its initstage attribute, as follows:
| immediate |
The init method is called immediately as the last stage of instantiation. |
| early |
The init method is called immediately after the view and its children have been instantiated. |
| normal |
The init method is called when the parent is initialized. |
| late |
The init method is called during idle time. To check whether init has been called, check the isinited property. Force calling init using the completeInstantiation method. |
| defer |
The init method will not be called unless explicitly requested by the completeInstantiation method. |
My Experience
For many of my views I was using “late”, but I decided to change it to “defer” to squeeze out some more performance. All views would only be instantiated on demand.
However the result was not what I expected. The performance was actually worse, because the delay when views became visible was even more noticeable than before. The requirement to initialise the views just-in-time lead to a noticeable lag in the UI.
It seems the “late” initialisation, using idle time, was quite efficient. So now I have changed everything back.
References
OpenLaszlo: optimising for a large number of views
OpenLaszlo: background loading of images
Tags: OpenLaszlo
Some discussion in the OpenLaszlo Forums gave me an idea for improving the performance of the deferred image loading in OpenLaszlo: optimising for a large number of views.
The idea is quite simple; if the views are being initialised in idle time (through initstage=”late”), then load the image when the view is initialised, that is in the “oninit” handler. The application will continue initialising views and loading images in the background, while the application is running.
<class name="myclass" oninit="this.load_image()">
<attribute name="imageurl" type="string" />
<method name="load_image">
var image = this.datapath.xpathQuery("text()");
if (image == null) return;
var imageurl="images/" + image;
if (this.getAttribute('imageurl') == imageurl)
return;
this.setSource(imageurl);
this.setAttribute('imageurl', imageurl);
</method>
...
</class>
...
<myclass name="myview" initstage="late" />
References
The enhanced class applies to the code in OpenLaszlo: optimising for a large number of views. In that post the code example used initstage=”defer”, which delays instantiation until completeInstantation() is called. For background image loading to work, you must use initstage=”late” instead of “defer”.
Tags: OpenLaszlo