Archive for category Flex

Away3DLite uses an inverted y-axis

I switched over from Away3D to Away3DLite, hoping that my performance issues would be solved. And indeed, Away3DLite is much faster than it’s big brother. However, I suddenly noticed that the y-axis seemed to be inverted (negative values above the root and positive values under the root). I first thought I made some errors with the camera and that I was seeing everyting upside down.

This post seems to explain the reason: The y-axis is inverted.

Strange thing is, however, if you place a cone on the scene, it is pointing upwards as you would expect when using a normal (not-inverted) y-axis. Makes it all a bit confusing, but now you know…

No Comments

Refer to an embedded image by a string variable

I’m making a small banner like application. All images have to be embedded into the application, but I want to be able to dynamically create these images. The position on the stage is configured using an external XML file. So, somehow, I have to be able to make references to the embedded images in my XML-file.

Example of an embedded image:

[Embed(source="assets/image.jpg")]
[Bindable]
private var myImage:Class;

An easy way to do this is of course:

var imgClass:Class;
switch (imageName) {
    case 'myImage':
        imgClass = myImage;
        break;
   case 'otherImage':
        imgClass = otherImage;
        break;
}

But there is an easier solution. Say that the image is embedded in MyView.mxml, then you can use this statement in MyView.mxml;

var imgClass:Class = getDefinitionByName(getQualifiedClassName(this)+'_'+imageName) as Class;

If you use the debugger, you’ll see that imgClass looks like: MyView_myImage. Or more specifically, if MyView.mxml is located in package, e.g. ‘views’, then imgClass = views.MyView_myImage;

No Comments

How to make a Dictionary bindable

The Dictionary class in Flex is not bindable. To make a Dictionary bindable, use the ObjectProxy class as a wrapper.

public class BindableDictionary extends ObjectProxy
	{
		private var _state:Dictionary;
		public function BindableDictionary() {
			_state = new Dictionary();
			super(_state);
		}

	}

Now you can set eventlisteners on the wrapper:

var bd:BindableDictionary = new BindableDictionary();
bd.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, handler);

I haven’t done full functional testing on this, but it seems to work fine so far.

No Comments

Monthly open source donation: Efflex – Flex effects

Efflex logoI wanted to donate in March to the Efflex project. There is a Paypal button on the site, but it doesn’t lead to page where you can actually donate. So I’ll wait until this button is fixed.

The project presents some excellent effects, especially for use with viewstacks.

Update april 14, 2010:
The button now works!

3 Comments

Flex HSlider tooltip does not respect stage boundaries

Had some difficulty in formulating a good title. But the problem is as follows:

If you have an HSlider and the right side of the slider is close to the right side of the stage, the tooltip may ‘walk off’ the screen. See the following image.  The grey background is the standard Flex Halo background. The green background is the color of my desk top.

This does not happen at the left side of the stage. If you drag the thumb to the left end of the slider, you see some smart things happening: the tooltip gets stuck at stage.x = 0;

I set myself to solve this problem and came up with a solution, which may also be called a hack. It uses mx_internal namespace, which means that it may not work in future versions of the Flex SDK. But I don’t know a better way. You do? Please let me know!

Step 1. Extend the SliderDataTip class:

package cbs.components.sliderClasses
{
	import flash.geom.Point;

	import mx.controls.sliderClasses.Slider;
	import mx.controls.sliderClasses.SliderDataTip;

	public class MySliderDataTip extends SliderDataTip
	{
		private var _slider:Slider;

		public function MySliderDataTip(owner:Slider):void {
			_slider = owner;
		}

	 	override protected function updateDisplayList(w:Number, h:Number):void {
			super.updateDisplayList(w,h);
			// Check if the tip overlaps the right side of the slider

			if (_slider) {
				var sliderPos:Point = _slider.localToGlobal(new Point(0, 0));
				if (this.x + w >= sliderPos.x + _slider.width) {
					this.x = sliderPos.x + _slider.width - w;
				}
			}
		}
	}
}

Extend the HSlider and override the onThumbPress function.

override mx_internal function onThumbPress(thumb:Object):void {
	// Hack this function, to be able to generate our own slidertip and
	// set a parameter.
	if (!dataTip) {
		dataTip = MySliderDataTip(new MySliderDataTip(this));
		systemManager.toolTipChildren.addChild(dataTip);

		var dataTipStyleName:String = getStyle("dataTipStyleName");
		if (dataTipStyleName)
		{
			dataTip.styleName = dataTipStyleName;
		}
	}
	super.onThumbPress(thumb);
}

That’s it!

No Comments

Flexlib WindowShade does not resize dynamically

Update: See comment#1 by Justin Mclean.

WindowShades resize to their content, even if you change the content dynamically. But it only does this until the first time you close and reopen the WindowShade. The reason is that it uses an effect to close itself. And by using this effect, it sets the ‘height’ property. And because of that, the component does not automatically resize depending on its content.

You can solve this by extending the WindowShade. First you have to override ‘runResizeEffect’. The main thing is to put an event listener to the effect end event.


private var _resize:Resize;
override protected function runResizeEffect():void {
if (_resize  AND _resize.isPlaying) {
_resize.end();
}

_resize = new Resize(this);
_resize.addEventListener(EffectEvent.EFFECT_END, handleEffectEnd, false, 0, true);
_resize.heightTo = Math.min(maxHeight, measuredHeight);
_resize.duration = RESIZE_DURATION;

_resize.play();
}

Then in the effect end handler, set the height to NaN so the WindowShade can resize automatically again.


private function handleEffectEnd(event:EffectEvent):void {
// We set height = NaN so that the component resizes automatically
// to the height of its children.

     height = NaN;
}

2 Comments

Flex renders chart labels too small

Flex rendered my chart labels too about  4 pixels high. This is what the documentations says about this topic:

When positioning and sizing labels, the AxisRenderer takes a minimum amount of the chart’s available space. If labels take too much space, then the AxisRenderer scales them. However, the AxisRenderer does not scale the labels to too small of a point size.

After some trial and error, I found out that this is not true if you use the gutter properties. For my ColumnChart I used both gutterLeft and gutterRight to a fixed value. Once I didn’t set the gutterRight property, the labels were rendered to decent sizes.

No Comments

Searching XML on attribute results in runtime error: Variable @ is not defined.

See this.

No Comments

Flex custom preloader does not center

All our projects use the same preloader. Like many people, we based our preloader on Jesse Warden’s tutorial.

Recently, it started doing funny by not centering. Google-ing around gave some hints, but none of them worked for me. Here is my solution.

Hide the preloader (line 6):


public override function set preloader(p:Sprite):void
{
_preloader = p;
p.addEventListener( ProgressEvent.PROGRESS , onSWFDownloadProgress );
p.addEventListener( FlexEvent.INIT_COMPLETE , onFlexInitComplete);
p.visible = false;
}

Use the ’stage’ property (see blog jaap kooiker). And unhide the preloader if we get a valid value for the stage width:

private function centerPreloader():void
{
if ((stage.stageWidth > 0) && (_preloader)) {
x = (stage.stageWidth / 2) - (clip.width / 2);
y = (stage.stageHeight / 2) - (clip.height / 2);
_preloader.visible = true;
}
}

Center the preloader on each progress event:

private function onSWFDownloadProgress( event:ProgressEvent ):void
{
centerPreloader();
updateProgressBar(event.bytesLoaded/event.bytesTotal);
}

1 Comment

Flex does not render all characters due to embedded characters in preloader

It is probably a problem on my machine (Mac OSX 10.5), but if I use Arial as a font, I get incomplete rendering of strings. Text with fontWeight set to normal renders okay, but it only renders a few characters when fontWeight is set to bold.

global {
fontFamily: Arial;
}

It will only show the characters ‘aegknrsvw’. If I use Verdana, there is no problem.

Update 24 feb 2010:
I found out what caused the problem. In our Flash preloader, we embed some Arial characters:

And these embedded characters were exactly the only characters that were rendered correctly by the application. Once I removed the embedded characters, everything worked fine.

No Comments