Most viewsystems use a 3x3 transformation matrix to represent the way in which a container modifies the coordinate system of its contents. This is usually very close to the implementation of such coordinate systems, and it's very powerful -- by modifying the transformation matrix, you can change rotation and stretch in an axis, as well as skew.
In designing Laszlo's coordinate system, we wanted to create an API that would be easy to use without thinking about it, but also provide enough power so that it would be relatively easy to do more complicated things. Alas, the transformation matrix was not really an option, because the Flash runtime doesn't have skew APIs.
In Laszlo, I can put a picture in my app as shown below. If I don't say otherwise, this view will be the size of its contents, which (in this case) is its resource. I've demonstrated this by putting a gray mask over the picture which has its width and height.
<canvas bgcolor="silver" height="275">
<view name="demoview" resource="gandalf.jpg"/>
<view bgcolor="black" opacity=".2"
width="${demoview.width}" height="${demoview.height}"/>
<button x="200">
Shrink
<method event="onclick">
demoview.setWidth( demoview.width - 10);
demoview.setHeight( demoview.height - 10 );
</method>
</button>
</canvas>
Also of note in the above example is the fact that I can change the view's size without affecting how it appears. This is, in fact, the default meaning of the 'width' and 'height' properties in lzx -- unless you say otherwise, they don't actually effect how a view gets drawn. This can be very useful for reasons (such as layout) that I won't go into now.
Here's a similar program, modified so that it has the behavior you were probably expecting.
<canvas bgcolor="silver">
<view name="demoview" clip="true" resource="gandalf.jpg"/>
....
</canvas>
By adding the clip="true" attribute, I have told the Laszlo runtime that this view should be clipped to its size. This is one way in which a view can be forced to be drawn at its given size. The other way is to tell the view to stretch (in "both" axes):
<canvas bgcolor="silver">
<view name="demoview" stretches="both" resource="gandalf.jpg"/>
....
</canvas>
One common issue when dealing with resources is the desire to keep the aspect ratio of an image. In simple cases (such as this one) it can be enough to know a resource's size and to use that to calculate an aspect ratio. In Laszlo, however, because the size of a view can be complex function of its contents, it is often necessary to know what size the view would have been, had it not been stretched. This information can be gleaned from the built-in properties "unstretchedwidth" and "unstretchedheight". Here's a program that preserves the aspect ratio of the image as it shrinks:
<canvas bgcolor="silver" height="275">
<view name="demoview" stretches="both" resource="gandalf.jpg"
height="${aspectRatio * width}">
<attribute name="aspectRatio"
value="${unstretchedheight/unstretchedwidth}"/>
</view>
<button x="200">
Shrink
<method event="onclick">
demoview.setWidth( demoview.width - 10);
</method>
</button>
</canvas>
I mentioned earlier that a view is the size of its contents. That holds true even when the view doesn't include a resource. Take a look at this case. Note that you can resize the enclosing yellow box by dragging the small boxes within it.
<canvas bgcolor="silver" height="275">
<class name="dragger" width="10" height="${width}"
onmousedown="ds.apply()" onmouseup="ds.remove()">
<dragstate name="ds"/>
</class>
<view name="demoview" stretches="both" bgcolor="yellow">
<dragger x="15" bgcolor="teal"/>
<dragger y="15" bgcolor="red"/>
</view>
</canvas>
You can see here that moving the draggable boxes inside the yellow box affects its size. This whole discursive enterprise has been an attempt to explain the seemingly curious behvior exhibited below. As you move drag the teal box, you're resizing the stretched view, but since you've set stretches, the apparent size of the box doesn't change -- just the extent to which it is scaled.
<canvas bgcolor="silver" height="275">
<class name="dragger" width="10" height="${width}"
onmousedown="ds.apply()" onmouseup="ds.remove()">
<dragstate name="ds"/>
</class>
<view name="demoview" stretches="both"
width="100" height="100"
bgcolor="yellow">
<dragger bgcolor="teal"/>
</view>
<text text="${ 'unstretchedwidth: ' + demoview.unstretchedwidth }"/>
<text text="${ 'unstretchedheight: ' + demoview.unstretchedheight }"/>
<simplelayout/>
</canvas>
Comments
I like this form of discourse, it lends itself well to explaining some of the more interesting options in LZX, as well as the thinking behind them.