Archive for the 'Actionscript' Category

Page 2 of 3

ArrayCollection weirdness

I ran into a head-scratcher today…

How can this code:

var index:Number = rows.getItemIndex(partition.placeholderRow );trace( index + " " + (rows.getItemAt(0) === partition.placeholderRow ) );

give this output?

-1 true

rows is an ArrayCollection with one element. partition.placeholderRow exists and is a valid object. I haven’t mucked around with rows.source at all.

Answer follows in comment (so you don’t peek ahead and cheat!)

New ObjectHandles Build

I posted a new ObjectHandles build yesterday.  It fixes a couple bugs and integrates some patches people have sent me including:

1) Graphical handle support
2) Fixed aspect ratio support
3) Ability to detect transparency & clicks 
There will likely be another build in the next week to integrate another patch and fix a few a performance issue.

XML Facade instead of value objects?

I have a project I’m working on where it’d be great if older versions of the software preserved information in the XML file format that it didn’t understand. For example, imagine if Version 1 (V1) of the software had this for a file format:

<data>
<value>1</value>
</data>

Now imagine if V2 of the file added an attribute

<data>
<value type=”number”>1</value>
</data>

It’d be great if you opened that second file with the V1 software and then saved it again, it would preserve the stuff it didn’t understand. Unfortunately that’s not how I usually write my value objects. Usually I do something like:

public class ValueObject{public var value:Number;public static function fromXML( xml:XML ) : ValueObject{var v:ValueObject = new ValueObject();v.value = xml.value;}

public function toXML(  ) : XML{var xml:XML = <data>;xml.value = value;return xml;}}

As you can see, anything in the file that it doesn’t understand is lost. But what if we followed a facade pattern for our data objects and did something more like this:

public class ValueObject{protected var source:XML;

public static function fromXML( xml:XML ) : ValueObject{v.source = xml;}

public function toXML() : XML{return source;}

public function get value() : Number {return source.value;}public function set value(val:Number) : void {source.value = val;}}

They both have the exact same API, but the second one will preserve XML attributes (or even nodes) that it doesn’t understand.

What about AMF based projects, especially when passing rich objects with a Red5 server? I know there’s a pretty seamless mechanism in place if properties aren’t known, but how do you get those unknown properties back to the server?

What other solutions or best-practices do other people follow for solving this issue?

Slow Flex Builder compile and refresh solution – Modules

For the past month I’ve been plagued with up to three minute compile times on Flex Builder 3 Beta 2. I’ve also been plagued with long several minute waits of “Refresing bin/”.

Last week I solved the issue for one of my projects and prevented it from happening to another.

Apparently embedding graphics causes a performance hit in compiling, refreshing directories, and even just before launching. So if you have a hundred or so of these:

<mx:Button icon=”@Embed(…)” />

You’ll be in a world of pain. The easiest solution is to move those embed calls into your style sheet and then compile your style sheet as a module.

Here’s how to make a style sheet module:

1) Create a new MXML module (file->new->flex->MXML module)
2) Add your stylesheet reference to that.

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Module xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”absolute” width=”0″ height=”0″
creationComplete=”trace(‘iconsloaded’)”>
<mx:Style source=”style.css” />
</mx:Module>

3) Next, remove the reference to your style sheet from your main application.
4) Now, in your main MXML or AS file add some code to load your module.

protected var styleLoader:ModuleLoader;protected function init() : void{    styleLoader = new ModuleLoader();    styleLoader.addEventListener(ModuleEvent.READY, onModuleLoad );    styleLoader.addEventListener(ModuleEvent.ERROR, onModuleError );    styleLoader.url = "IconsModule.swf";       styleLoader.loadModule();}protected function onModuleLoad( e:ModuleEvent ) : void{    maximize();    var mainApp:MainApplication = new MainApplication();    mainApp.percentHeight = 100;    mainApp.percentWidth = 100;    addChild(mainApp);   }

protected function onModuleError(e : ModuleEvent ) : void{    Alert.show("Could not load module IconsModule.swf","Error",Alert.OK );}

You can see there that I intialize my main application component after the module has loaded. I didn’t have to do this in a Flex app, but in my AIR app that component wouldn’t get all of the new styles if created before the module was loaded.

Option 2

Sometimes, it wasn’t practical for me to put the embedded graphic in a stylesheet. In those cases I:

1) Made an interface listing all the embedded graphics

public interface MyGraphicsModule{// Bindable tags are there purely to suppress warnings,// these properties never change after startup.[Bindable(event="moduleChanged")] function get addIcon() : Class;...}

2) Make a class that implements that interface and extends ModuleBase, also embed the graphics in there.

public class MyGraphics extends ModuleBase implements TimeLinerGraphicsModule{[Embed(source="/art/toolbars/add.png")]protected var _addIcon:Class;public function get addIcon() : Class { return _addIcon; }

...}

NEVER import or otherwise use this class into your application. The goal is to keep it completely separate.

3) Create a module manager class

public class MyModules{[Bindable] public static var graphics:MyGraphicsModule;}

4) Set MyGraphics to be a module that gets built in your Project->Properties->Flex Modules settings.

5) Load your module somewhere at startup

public function loadModules() : void{graphicsModuleLoader = new ModuleLoader();graphicsModuleLoader.addEventListener(ModuleEvent.READY, onModuleLoaded );graphicsModuleLoader.addEventListener(ModuleEvent.ERROR, onModuleLoadFailure );graphicsModuleLoader.url = "MyGraphics.swf";graphicsModuleLoader.loadModule();}

protected function onModuleLoaded( event:ModuleEvent ) : void{if( event.target == graphicsModuleLoader ){var o:Object = event.module.factory.create();MyModules.graphics = event.module.factory.create() as MyGraphicsModule;}}

6) Find the spot in your code that used that icon and replace it

So this:

[Embed(source="/art/icons/addIcon.png")]public var addIcon:Class;

Would become this:

public var addIcon:Class = MyModules.graphics.addIcon;

This all seems like a pretty tedius job to do, but I ended up writing a perl script to scour the source tree, find all the references, and replace them for me. Unfortunately I did that script as part of my day-job and can’t share it with everyone right now. I’ll ask for permission on Monday.

The end result was we went from a 3.5 minute wait from saving a code change to executing the application to a 20 second wait. Not too shabby considering the size of the codebase we have.

SwfControls (Graphical Buttons and Popup Menus)

On Saturday I blogged about a new component I was working on and I got a few responses saying it looked really useful. So I threw up a project page and it’s available for download.

I’m calling it “swfControls” for now, but I’m hating the name the more I think of it. Any suggestions? At this point, I’m really considering bundling ALL of my controls together, maybe I should just do that to avoid naming them all.

http://rogue-development.com/swfControls.xml

Right now there’s just a binary SWC for download, I’ll get full source posted soon.

Enjoy!

Log Viewer & XRay

I’ve made a bunch of changes to LogViewer, you can get the latest package over at:

http://www.rogue-development.com/logViewer.xml

But much more interestingly, I made the changes in direct response for my desire to improve the logging facilities in XRay.

In case you’ve never heard of it before, XRay is the best tool for debugging Flash applications out there. It’s written by a guy named John Grden that I’ve had the opportunity to work with for the past year or so. Last week I told him about LogViewer and he added it in to XRay. But it just didn’t feel right. It looked clunky and there was some functionality that should be there but was missing. So for the past couple days I’ve been hacking apart LogViewer, adding in a few features, and making it look a little prettier. Here are the results…

As you can see, the search functionality remains, but with a find-previous option listed.

Two new features include the ability to filter based on a text string, and the ability to highlight lines that contain a text string. Both very useful when you have an application spewing large amounts of logging information at you.

With any Luck, we can get these changes wrapped up over the next week to a release-quality state and post it for all to use.

ObjectHandle component updated

ObjectHandles, the easy way to add user resizing & movement of objects to your flex application, has been updated.

Changes include:

- Initial rotation support added (still needs some tweaks). Thanks
goes to Alexander Kludt for contribution of most of this feature.
- Metadata for events added. (Thanks Thomas Jakobi!)
- Bug fix for making ObjectHandles dynamically through actionscript
instead of in an MXML document.
- Ability to turn mouse cursor support off (since they are ugly right
now).

A new demo is up and downloads can be found at:
http://www.rogue-development.com/objectHandles.xml
(Clear your browser cache before viewing the demo again, I’ve seen it
not refresh sometimes, even on a shift-reload on my browser)

Enjoy!

AS3 Drawing API oddity

I have a weird bug that I’m having trouble figuring out. I have the following code:

comp.graphics.clear();
comp.graphics.lineStyle(5, 0×888888);
comp.graphics.moveTo(0,0);
comp.graphics.lineTo(0,50);
comp.graphics.lineStyle(0, 0);
comp.graphics.beginFill(0×188888);
comp.graphics.drawCircle(10,10,5);
comp.graphics.endFill();

I would expect that to draw a vertical grey line with a filled in circle to the right of it. What I actually get is this:

It’s like flash is drawing my circle and then doing a flood-fill outside the circle instead of inside it like it should. If I remove the call to drawCircle(), I get similar results but without the circle.

My solution was to draw the line and the circle on different objects, but I’m unclear on why this is necessary.

ObjectHandles now has mouse cursor support.

ObjectHandles, the easy way to add user resizing & movement of objects to your flex application, has been updated.

Now, when mousing over the component or the various handles an appropriate mouse cursor will be displayed.

There’s been a lot of interest from people about this component. It’s seen over 400 downloads and I’ve received quite a few emails about it. If you interested in following this project more closely, I’ve set up a google-group where I plan to announce new versions and people can ask questions. To join, go over to:
http://groups.google.com/group/objecthandles

Downloads, examples, etc can be found on the project page:
http://www.rogue-development.com/objectHandles.xml

If the example on the project page seems out of date, you may have to clear your cache. I’ve found some browsers don’t refresh i-frames like they should.

Log Viewer

I’ve started a new project to make a flex component to quickly display largish amounts of text. It’s main purpose is to display logging information on screen. It’s uses a semi-intelligent algorithm to re-use on screen components and batch UI updates in groups.


http://www.rogue-development.com/logViewer.xml