OpenLaszlo and Windows Vista

I upgraded to Windows Vista recently, and ran into an issue with OpenLaszlo right away. This post will be relevant to anyone who is using Vista as their development environent.

By default, the OpenLaszlo developer installs itself in C:\Program Files\OpenLaszlo Server xxx.

The problem this causes is that by default, the my-apps folder lives under C:\Program Files. If you have an administrator Windows account, you’ll be able to save your .lzx files in my-apps. And you’ll be able to compile them fine too. The problem appears when you try to save a SOLO application. The OpenLaszlo server will try to save the SWF file next to its LZX source code – somewhere in my-apps, under C:\Program Files. Windows Vista no longer allows programs to write files to C:\Program Files. It’s all supposed to go elsewhere (e.g. C:\Documents and Settings\). Since this is a new restriction, Vista works around it for older programs using something called folder virtualization. Essentially, the operating system allows Tomcat to create a “ghost” of the SWF file, under C:\Users\username\AppData\Local\VirtualStore\Program Files\OpenLaszlo Server 3.4.x\my-apps\…

The quick workaround to this is to install the dev install of OpenLaszlo under a different location. e.g. C:\Programs\OpenLaszlo Server xxx.

Context Menu Guidelines

OpenLaszlo allows users to define custom context menu (i.e. right-click menu) options throughout your applications. There’s two classes involved here: LzContextMenu and LzContextMenuItem. The former represents the context menu itself, and the latter represents a single option within it.

Some capabilities and guidelines:

  • Stick to Flash Player 8 or DHTML for your runtime, if you plan to use custom context menus in your application.
  • Right-click behavior works very differently from left-click behavior: The view need not be clickable to respond to right-clicks. However all views, clickable or not, intercept the right mouse click. This means that a subview will always trap a right-click event before its parent.
  • You can specify a context menu on a per-view basis. You can also specify a generic application-level context menu.
  • There are some words you cannot seem to use as LzContextMenuItem captions. “Save” and “Delete” are two I came across. You can add a space character the name – e.g. “Save ” – to work around this.
  • Views have a .contextMenu attribute as well as getContextMenu() and setContextMenu() methods.
  • Context menus can be created on-the-fly.

The second point above is probably the most important thing to bear in mind. Consider a view containing a text field. The view has a context menu:

Notice how if you click on the text field, you don't get a custom option in the context menu, but if you carefully click in the yellow area above, below or to the right of the text, you do see a "Chop" option?

The workaround here is to place a transparent view in front of the subviews, that's the full height and width of its parent. If it's not clickable, it will allow left clicks to pass through, but right clicks will pass through. Unfortunately, because of a bug, that view can't really be transparent, but instead it needs to have a bgcolor, and a low opacity. You can see the improved effect in the application below:

Source code for simple and better context menu.

Finally, remember that the LzContextMenu object will send an onmenuopen event, when the menu is opened. You can use a delegate to trap this event, and call a method to create all the entries in a context menu, just before it is displayed.

Using a Scrollbar

Using a scrollbar in LZX is so deceptively simple, that developers often have a hard time figuring it out. Below is an example of a scrollbar in action:

There are two LZX classes you can use to make a view scroll its contents: scrollbar and hscrollbar. scrollbar is vertical; hscrollbar is horizontal. The two orientations will work together automatically. The scrollbar is designed to scroll a single view within a clipping container. i.e. if you want to scroll multiple views (which you almost always will), you should wrap them in a single containing view.The diagram below shows the layout of views:

Scrollbar Diagram
Scrollbar Diagram

Some guidelines:

  • The clipping view should have a defined width and height. It's OK if they are constraints.
  • The clipping view must clip its contents. (clip="true").
  • The scrolling view must not have a defined height. Exploit the stretchy behavior of views here.
  • Define a width for the scrolling view, so that it leaves room for the scrollbar.
  • The scrollbar and scrolling view must be siblings. If not, you'll have to set the target attribute.

Download an example of using the scrollbar