Archive for the ‘Flex’ Category

ComboBox with variable width dropdown.

Monday, January 14th, 2008

the main view in my application changes it’s data quite frequently, and uses a comboBox as one of it’s controls. Initially I’d just left the comboBox’s width unset and it was happy to resize itself according to the data presented.

However, our “designer” was not happy…

It was decreed that the comboBox should remain at a fixed width (In it’s collapsed state).

The data labels it presents varies considerably in length, and to set it’s fixed width to the longest would a) look stupid in most cases b) require measuring all possible labels before deciding on the width.

So, I decided that I would make the dropdown size itself to the widest label for any one current dataset in it’s dataProvider, at the point at which the dataProvider changes.
I also thought about a dataTip function in a similar fashion to that of the tree control, but decided that the dropdownwidth made more sense since generally speaking labels for our data are of a similar length in any set, so it’s a different question than just the odd one long label in the dropdown.

This proved to be fairly straightforward to get working, though it was new to me and I have to admit I still lack confidence that I’ve done it in entirely the correct way.
However, it does seem to work OK so thats probably good enough until I learn a little more.

Measuring the labels widths was easy (dropdown.measureWidthOfItems) , and initially it seemed to make sense to do that and alter dropdownWidth when the dataprovider changed (in collectionChangeHandler() ) .

However, that lead to a dropdown that was less than the width of the base which was ugly, so I thought I’d “just” do dropdownWidth = Math.max(newDropDownWidth, this.width).

That, of course, turned out to be a problem if the dropDown was visible at the time (since that affects the measured width of the component), and lead to some rather strange results :(
Some experimentation showed that the “FlexEvent.VALUE_COMMIT” event occurred at a nice time to measure and set what the new dropdownwidth should be (The dropdown is hidden before the event occurs, so you get the “base” width at that point. On reflection, it may have been worth getting the width of the “base” element somehow, but I didn’t look for that.

The other thing that needed attention was that “measureWidthOfItems” does not take into account the presence or otherwise of the scrollbar on the dropdown.
I detected it’s presence by using dropdown.maxVerticalScrollPosition > 0, but initially hardcoded it’s width to the standard 16 pixels(it was late at the time).
There’s no direct way to get the scrollbars width (it’s protected within the standard dropdown), instead you must extend your dropdown with a method that reads and returns it.
Though I’d not done that before, it proved to be easy enough. However, I’m slightly suspicious that the fact I use a cast to get my extended dropdown class before being able to call the scrollbar width method means that I’ve not quite got it 100% right. But considering it only gets called when the dataProvider changes, I’m not too bothered in practice…

All that remains is to make an example featuring cute puppies…

View example (right click example for source)

Transfering my focus to flex presentation…

Tuesday, January 8th, 2008

For a long while now, I’ve been building (if you like) the model of my application, using a very basic gui about whose looks and usability I’ve not cared about too much…

As the application has neared it’s desired functionality and it’s quirks and bugs have decreased, I’ve been able to devote more time to how it’s gui looks and works.

I ended up using cairngorm as a framework (though nearly went for pureMVC, which I’ll probably try on another smaller project in due course for interests sake), so in theory I ought to be able to mess about with my presentation without breaking anything too badly. It’s worked out well so far, on the face of it a little verbose in terms of writing events, commands, delegates etc for everything I do, but the payback has been worth it. I no longer have to remember what particular hack I pulled or worry so much about changing that hack breaking something else since there is a clear path for everything. Changes have been easier, what at first seemed as if it could be restricting is in fact liberating.

I’m actually looking forward to the gui side of things, it’s a whole new area that I’ve not been able to devote much time to since I took up flex.
As I start writing the odd custom component and delving into the framework source I’m getting a better understanding, learning some new stuff and generally getting interested again.
Yes, I have a few books on as3 and flex, but I always find that there is no better way to learn than to do.

The first thing of any interest was the tree thumbnails example I posted, at the moment I’m attempting to bend comboBox to my will. I’ll post on that when it’s done to my satisfaction (There being a couple of things that are still troubling me) and I feel I’ve understood what I’m doing a little better.

You wait ten years for a flash html renderer, and then two come along at once!

Thursday, January 3rd, 2008

This is one thing that I am, and have been, really really missing in flash. My clients, of course, fail to understand why text handling in flash is basic, from their point of view it’s all text that appears on the interweb and why can’t flash “just” display the same kind of text???

Standing in their shoes, I do understand it, but in mine I appreciate the flash player difficulties (A bit, anyway :) I wish it were not so, nevertheless ).

Well, I’ve heard a whisper of flash player 10 having the ability to display tables in text fields, which would be nice, but then I guess we’ll see in good time.

In any case, just as the issue reared it’s head properly at work, I get not one but two little rays of sun shiney hope poking through the clouds, literally in the past couple of days.

Firstly, Alex Harui posted some code and what I consider some quite insightful comments on his blog here.
It is by his own words incomplete and possibly buggy, but that’s fair enough and I’m still very pleased to see it.
As he rightly supposes, in my case I only really need a small subset, and having code to start from will be an enormous leg up compared to starting from scratch.
So far I’ve only had 3/4 hour to play with that one, but it looks promising.

Secondly, another library (htmlwrapper) comes along, open sourced on google code (via FlashcodersNY). Not had much of chance to play with this one either, but reading the docs html tables are yet to come (a shame, since the text I have to render is table based, and unfortunately a little haphazard). Still, I’m looking forward to checking this out as well.
Again, just having something to start with and code to play with should be a great thing.

Many thanks to the respective authors for releasing the code, it’s so much appreciated.

Flex tree control with image tooltips*

Wednesday, January 2nd, 2008

* and some cute puppies, at last :)

Most of the assets my main work project displays are bitmaps, and we tend to use tree controls for most navigation around any given product.

A long running and popular request was for there to be a thumbnail tooltip of the resource appearing when an item in the tree was rolled over.

This seemed like a job for a dull day over Christmas, so I gave it a go …

My first thoughts were that this was essentially a datatip rather than a toolTip per se, so I had a dig around and implemented a quick custom dataTipFunction function and showDataTip=”true” on the standard tree control, then looked for a way to customise what the datatip position was and how to change it to a custom tooltip. That appeared to be a bit of a dead end, or at least one that would require a fair bit of effort.

The positioning of the renderer ToolTip is in a private function for TreeItemRenderer, so there’s no overriding it in an extension of TreeItemRenderer.
I didn’t want to make a whole new implementation of the renderer either, plus if I just copied the existing one to modify there is an include to “/core/Version.as” in the framework which was another complication.
On reflection, it seemed as if the existing implementation of the dataTip was something that was useful enough that I didn’t want to lose it (It displays a tooltip of the label text if that text is too wide to be displayed within the width of the tree).
All in all, that approach was beginning to smell bad.

So, I took the simpler approach of just using the existing itemRollover event, and setting the toolTip on the tree rather than the item renderer, positioning it according to my needs. So far it’s working well enough.

Getting the data from the Rolled over item is easy, in this example I cast it to XML since I only use XMLList for my trees dataProviders.
It would probably be better to allow for other forms of dataProvider as well.

I take a custom attribute of the tree nodes XML as the URL for the thumbnail, and set the trees toolTip to that.

Making a custom toolTip to display the bitmap thumb is easy enough, many thanks to Rich Tretola for his example here.
Briefly, you set the tooltip to your own implementation of IToolTip in a function handling the toolTipCreate event the Tree provides as standard.

Being somewhat lazy, I used Rich’s classes in this example, though I did add some code to keep the positioning of the tooltip once the (unknown size) image loaded, and to allow for the fact that it could in fact go off screen at times (so I reposition it back on if so).
I should probably make that bit of code more generic, however, and add it to the CustomToolTip class rather than the specific ImageToolTip.
That job is now on the list …

This same approach works just as well on a List control, by the way, as one would expect.

I think that’s it … Bear in mind that this is just a basic demo, and there are few things that would need doing to make it “production ready”.

TreeControlWithThumbnails

Right Click on application to view & download Source Code.

Run This Code

Annoying bug in flash player ConvolutionFilter (maybe others?) with multicore processors

Monday, December 31st, 2007

I’m not quite sure where I report this one (mainly since I’ve made no effort to find out). Though Alex Harui was (I believe) going to file a report after I posted this to flexCoders.

Since some bitmap filter functions were made multi core aware and capable, I’ve been suffering the occasional line across the results of one the convolution filters that I’ve been using for edge detection of a colour in an image.

Reading Tinic Uro’s post here : http://www.kaourantin.net/2007/06/multi-core-support.html, it would seem that some bitmap operations are now split into two, and the results joined when both threads complete.

It would appear that there’s a edge case error in the flash player code to do with this.

The flex code below is a simple test case, for me it normally displays a horizontal line where there should be none with the first couple of dozen tries, but only on a multi core machine (windows, I don’t have a recent mac to test on :( )

It’s possible to set DisableMulticoreRenderer=1 in mm.cfg locally for ones flash player, unfortunately that’s not really an option for our clients.

Never mind, We are not releasing yet, it’s not a show stopper, and I’m sure it will get fixed in flash player in the future.

Download test case mxml here : Test case for multicore filter bug

See the test in action here : http://www.ifeedme.com/blog/customContent/filterbugexample/

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” width=”400″ height=”440″ creationComplete=”init()”>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.core.UIComponent;
private var _bmpData:BitmapData;
private var _bmp:Bitmap;

private function init():void
{
_bmpData = getTestBitmapData();
_bmp = new Bitmap(_bmpData,"auto",true);
var ui:UIComponent = new UIComponent();
ui.addChild(_bmp);
this.addChild(ui);
}

private function getTestBitmapData():BitmapData
{
var bmpData:BitmapData = new BitmapData(400,400);
bmpData.fillRect(new Rectangle(30,30,340,340),0xFFFF0000);
return bmpData;
}

private function testFilter(bmpData:BitmapData):BitmapData
{
var matrixX:int = 3;
var matrixY:int = 3;
var o8:Number = 1.0/8.0; //one eighth
var matrix:Array = new Array
(-o8, -o8, -o8,
-o8, 1, -o8,
-o8, -o8, -o8);

var col:uint = 0xFF00FF00;
var edgeFilter:ConvolutionFilter = new ConvolutionFilter(matrixX,matrixY,matrix,1.0,0.0,true,true,col,0xFF);

bmpData.applyFilter(bmpData,bmpData.rect,new Point(0,0),edgeFilter);

return bmpData;
}

private function test():void
{
if (! demonstrated)
{
_bmp.bitmapData = testFilter(getTestBitmapData());

var i:int = 190;
for(i=198;i<202;i++)
{
if (_bmp.bitmapData.getPixel32(40,i) != 4278190080)
{
demonstrated = true;
mx.controls.Alert.show("DOH! :( multicore bug found ??? \n See horizontal line artifact at \n Y = " + i);
}
}
}
}

]]>
</mx:Script>
<mx:Boolean id=”demonstrated”></mx:Boolean>
<mx:Button x=”5″ y=”405″ label=”TestFilter” click=”test()” enabled=”{!demonstrated}”/>
<mx:Button x=”85″ y=”405″ label=”Clear” click=”{demonstrated = false}”/>

</mx:Application>

Extracting an image(jpeg or png) from a raw ByteArray in actionscript / flex

Friday, December 28th, 2007

This is a question I see asked fairly regularly, yet it seems to be a hard one to google for and get an easy answer.

In my current main project I have a need to pre load a large amount of images as quickly as possible, and yet kill any existing preloads immediately should circumstances change. Some casting around lead me to the StreamLoader class which offers all I needed, with the proviso that the result is a raw ByteArray.

So, I needed a means to convert that ByteArray to a bitmap or BitmapData.

Some digging around lead me to the fact that the Loader class will do that for a ByteArray that is read from a jpeg or png file.

The code looked something like this for an existing ByteArray in a variable named “bytes” :

var loader:Loader = new Loader();

loader.loadBytes(bytes);

Now, the bitmap *will* be available in the loaders “content” property, but do not assume that just because you gave it a preloaded bytearray that it will be *immediately* available. Or you will be sad and confused, as was I :)

No, the bitmap will only be available once the loader.contentLoaderInfo complete event fires.

So, add an event listener for the complete event :

loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderCompleteHandler);

Then get the bitmap from the loader at that point in time :

private function loaderCompleteHandler(event:Event)

{

var loader:Loader = event.target as Loader;
var bmp:Bitmap = Bitmap(loader.content);

}

Note that I’ve omitted all the usual removing of event listeners, unloading loaders etc for the sake of brevity.

So there you go, that’s how it’s done. Now I know the answer it makes perfect sense, but initially it did seem to work not quite as I expected it to.

Since then I’ve had occasion to use this a couple more times, such as getting a server side processed image from .NET via fluorine remoting services, and in AIR (grabbing images stored as ByteArray blobs in a sqlite database).