Flex/Flash/Actionscript

Demo Mashup of various Flex 2 community components

Here’s a little demo Flex app I put together. It’s another MXNA RSS reader (I know, I know, like there aren’t anough of those already). But really I didn’t start out making an RSS reader, I started playing with Ely Greenfield’s FishEye component. Then I figured it would be cool to have the icons I used for the FishEye component rotate a badass 3d cube thingy, which uses the awesome distortion classes from Alex Uhlmann. And of course it’s got to have the requisite web 2.0 reflection, which was made by Ben Stucki. Then I figured that I should have something sweet displayed in the rotating cube, and I remembered Josh Tynjala’s TreeMap component. And I remembered seeing a demo of an MXNA reader that Josh had made using that TreeMap component, so that’s how I ended up making another RSS reader.

Why is this important?
There’s been a lot of discussion recently about the Flex component developer community. Projects are starting, developers are coming out of the woodwork, the community’s buzzing. This little demo shows a combination of open-source Flex components from four different developers, put together by a fifth developer (me). All the code I used has been released by the authors for free use. It’s all available to browse through, learn from, improve, etc. Now if only it was all consolidated into one central location… <hint, hint>

And we’re only at the beginning. Keep an eye out for new Flex components, my prediction is that we’re going to see an avalanche of awesome components.

So anyway, here’s my little demo. It just loads the most recent posts on MXNA for whatever category you select (by clicking on one of the icons at the bottom).

Here’s the recipe:

Add them all together and this is what you get:
[Or launch it in it’s own window: here’s the link]

This movie requires Flash Player 9.

Source for this demo isn’t released yet, I put it together quickly, so it’s not quite up to my own standards.

Standard
Flex/Flash/Actionscript

Announcing FlexLib – open source Flex component library

FlexLib

I’m pleased to announce the FlexLib project hosted on Google Code. This is an open source library of UI components for Flex 2. The goal of this project is to gather all the great components that people are releasing on blogs, Adobe Exchange, mailing lists, etc. and create a central open-source project that everyone can contribute to. Hopefully this will provide a central location for people to find custom Flex components.

What is it?

  • It’s open-source, released under the MIT license (about as free a license as you can get)
  • It’s on Google Code, which means SVN access for members, issue tracking, wiki, etc.
  • You can contribute your code!

What’s in it?
We started off by contributing a few components to get the ball rolling. See the full list of components on the Google Code project page. The quick list of components follows: ConvertibleTreeList, Draggable Slider, PromptingTextInput, Scrollable Menu Controls, SuperTabNavigator, Alternative Scrolling Canvases, Horizontal Accordion.

But more important than what FlexLib currently has in it, is what’s going to be in it? And of course the answer is: everything you have! If you’ve been developing components and posting the source on your blog, we’d love for you to round up your collection of components and integrate them into FlexLib.

Why another place for components?
The question has been raised as to whether there’s any reason to create yet another place for people to find Flex components. We certainly don’t want to add to the clutter and just make another barely-used source for components. We’ve already got the Adobe Exchange, tons of blogs, and the nice newly released flexbox app that tries to aggregate these sources. So here’s my thinking:

  • This is going to be a high-quality source for components. This means code gets reviewed by project members and components are well documented.
  • We can build off each other’s code if it’s all in the same project. Component developers aren’t in their own little blogosphere microcosms, if we all have one source for everyone’s code we can all extend and improve the library.
  • We can consolidate our effort. I know that I’ve spent time working on some component or another only to find out that some other Flex blogger has been doing the same thing. Hopefully this will help us coordinate and work together.

Who’s involved?
The project was started by Darron Schall and myself, with the input and help of Mike Chambers and Ted Patrick from Adobe. But FlexLib is meant to be a community project, so we’re inviting all Flex developers who can contribute to join. Take a look at the How to Contribute wiki page, start playing with checking out the project from the SVN repository, join the discussion group for the project, and most importantly send us your code!

Standard
Flex/Flash/Actionscript

Quest for the Perfect TabNavigator – Part 3 (with source)

[UPDATE 02-08-2007 4:05 pm] Added the ability to adjust the scroll speed via scrollSpeed property. Changed scrolling buttons to work via mouse down or mouse over, customizable with the startScrollingEvent and stopScrollingEvent properties. Made the drag proxy image a copy of the bitmap of the tab so it looks like you’re dragging the actual tab.

This is the culmination of my work on making a better TabNavigator component for Flex. This includes lots of enhancements that have been discussed in the Flex community. We got draggable, re-orderable, closable tabs! We got scrolling tabs if too many tabs are open! We got a drop-down list of all open tabs! It slices, it dices! But seriously, it’s got a lot of stuff. I’ll try to go over everything briefly here, but the real way to figure this out is to download the source and go through it yourself. I tried to comment the bejesus out of most of the classes, so you should be able to follow along pretty well.

I’ve gotten ideas from various flexcoders threads, the sample posted on Flexible Experiments, the sample on code zen, darron schall’s demo, etc etc.

In keeping with Ely Geenfield’s naming conventions I’ve dubbed this component SuperTabNavigator. It is pretty super after all. This is a subclass of TabNavigator. I was actually able to do everything I wanted to do without having to copy/paste the code of TabNavigator, so using this component shouldn’t add too much to your Flex app’s footprint. The source included also includes the source of previous components I created that allow menu components to scroll. The SuperTabNavigator uses the scrolling version of the PopUpMenuButton for the button to the right of the tabs. So those scrolling menu components are thrown in here.

OK, so what makes this SuperTabNavigator so super?

Draggable, re-orderable tabs
You can drag tabs around to re-order them. An indicator shows where the tab is going to be placed if you drop it. You can drag tabs from one SuperTabNavigator to another. You can control the dragging ability by using the new dragEnabled and dropEnabled properties of the SuperTabNavigator. Those properties should work as you’d expect. The indicator is skinnable via CSS using the indicatorClass style.

Closable tabs
Tabs can display a close icon that will allow the user to close the tab. You can control if and when the close button is shown by setting the closePolicy property of a SuperTabNavigator. Possible values are: SuperTab.CLOSE_ALWAYS, CLOSE_SELECTED, CLOSE_ROLLOVER, CLOSE_NEVER. That should give you fairly good control over how the close buttons show up. The close button is fully skinnable via the CSS property closeButtonSkin just like any other button.

Scrollable tabs
If the tabs get too long to display then they will scroll. This means a little button on the right side will appear with an arrow and if you mouseover this arrow the tabs will scroll. The left and right buttons are skinnable via CSS with the leftButtonStyle and rightButtonStyle styles. You can set what the smallest acceptable width for the tabs is by using the minTabWidth property. If you don’t set tabWidth then the tabs should keep their natural width until there are too many to fit, then they’ll squish until they reach minTabWidth, then they’ll scroll. If you were to set minTabWidth to 0 then there would be no scrolling.

Drop-down list of tabs
On the right side is a PopUpMenuButton that shows a drop-down list of all open tabs. Selecting a tab in this list will obviously select that tab. Try selecting a tab that isn’t visible and see the sweet tween motion as the tab scrolls into view. The display of this drop-down button is controled via the popUpButtonPolicy policy, which can be set to POPUPPOLICY_AUTO, POPUPPOLICY_ON, or POPUPPOLICY_OFF. Auto means the button is shown if there is more than 1 tab. ON obviously means it’s always shown, and OFF means it’s never shown. That button is skinnable too via CSS with the popupButtonStyleName style.

So that’s the gist of it. But to really understand what the component can do you should read the source code. I’ll work on getting the ASDocs generated to accompany the code.

Now I’m sure you’ll read all this and say, “Wow, what a perfect TabNavigator, I had no idea such an amazing TabNavigator could exist. Surely there are no features missing.” Well, in fact, there are some more features I’d like to include. Here they are in no particular order:

  • multiple rows of tabs
  • tabs down the left or right sides or on the bottom
  • ability to not show the close button for individual tabs
  • right-click on tabs to get menu for “Close Tab” or “Close Other Tabs”

And you would then say, “But no, please, if such a TabNavigator existed I would be blinded by it’s perfection.” And I would reply, “Prepare yourself.”

View the source
. [Note: you need the Flex 2.0.1 update to use this code]

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

Using hitTestPoint or hitTest on Transparent PNG images

On a previous unrelated blog post, someone posted a comment that had to do with using the hitTestPoint() method with transparent images. I was about to respond by saying I don’t have any experience playing with hitTestPoint, I’m not sure why that question was posted to my unrelated post, and I don’t have an answer. While I was formulating my response in my head, I read up a bit on hitTestPoint (in the DisplayObject class) and hitTest (in BitmapData). And before I got done figuring out how to phrase “I don’t know, go ask someone else,” I thought that maybe I actually did know and figured it would be interesting to investigate a solution.

So here’s my take on DisplayObject.hitTestPoint() and BitmapData.hitTest(). At the end of the post is an example that does some hit testing on two images, one is saved as a transparent PNG and one as a SWF.

hitTestPoint


DisplayObject.hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false)

This method returns true if the point is over a transparent area of a bitmap image. Using the shapeFlag boolean makes it so the method returns false over an area of a vector image that has no shape. This is not the same thing as a transparent pixel of a bitmap image. It might be a little confusing in the documentation, but I think it makes sense (maybe it needs a sentence or two of clarification). Basically in a vector image you have no data in transparent areas. In a bitmap image there is a pixel there, and that pixel has an alpha value of 0. But that’s actually different than not having anything taking up that x,y coordinate. So the term “shapeFlag” does in fact only refer to shapes in vector images. Thank god they didn’t call it “transparentFlag” or something like that since that would make it even more confusing. It’s not about transparent pixels versus opaque pixels. It’s about “is there something there or not,” and a transparent pixel is still a pixel.

hitTest


BitmapData.hitTest(firstPoint:Point, firstAlphaThreshold:uint, 
         secondObject:Object, secondBitmapDataPoint:Point = null, 
         secondAlphaThreshold:uint = 1):Boolean

This function is confusing as hell, and I strongly suggest Adobe write some further documentation with a few examples on how to use this. This is a powerful function because you can test for a hit between a BitmapData object and multiple other types of objects (a Point, Rectangle, or another BitmapData). But it’s hard to figure out how to use it. Like, wtf does the first parameter mean (firstPoint)? I think it’s only used if you’re testing between one BitmapData and a second BitmapData. I was interested in testing a BitmapData against a point, so I just passed a point of 0,0 and it seemed to work right.

But anyway, griping about documentation aside, these two methods are different. If you’re interested in testing for a hit on a bitmap image and you don’t want to count the transparent areas, then you must use BitmapData.hitTest. You cannot use DisplayObject.hitTestPoint because that will return true for transparent pixels.

So I’ve made a simple utility class that solves this problem. I called it HitTester and what it does is it first checks for a hit using DisplayObject.hitTestPoint. If that returns true it means we’re at least within the bounding box of the image. Then it checks using BitmapData.hitTest. To do this it creates a temporary BitmapData object for the Image and runs the hitTest method.

To use the class you do something like this:

HitTester.realHitTest(image1, new Point(event.stageX, event.stageY));

The example below shows using the DisplayObject.hitTestPoint versus using my HitTester utility class. Move your mouse over the images and you can see the hit test results. Both images are basically the same, but I saved the left one as a transparent PNG and the right one is a SWF. You’ll see that the normal hitTest Point method works to accurately test for opaque areas of the SWF, but not for the PNG. The HitTest class basically just makes the hit testing of the PNG work like it does for the SWF.

View the source.

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

Building a Gantt Chart Component in Flex

Here’s my intial attempt at making something that resembles a Gantt chart. There’s been some good discussion about this recently on flexcoders. People have suggested a few different ways of making a Gantt chart. Here I’ll outline the main ideas that have been thrown around and then I’ll go over the example that I came up with.

Option 1: Use the DataGrid as the base. This was the approach that Andrew Trice used. This is also the approach that I took, see the example below. The idea here is that each row of the DataGrid will serve as each item of the Gantt chart, and all we need to do is specify a custom itemRenderer to display it.

Option 2: Use the charting classes as the base. Ely Greenfield’s got an example of making a chart similar to a Gantt chart (follow the link and find: Series Type >> Columns and Bars >> Floating Bars). The basic idea here is that you use the chart classes and extend them to turn them into a Gantt chart. I decided against this because 1) I haven’t investigated custom charting and reading Ely’s blog makes it seem fairly complicated (Ely, I know you try to make it easy for us 🙂 ) and 2) I liked the itemRenderer and itemEditor approach that a DataGrid takes, which would allow me to have editable controls in there.

Option 3: Use the scheduling framework from Adobe Consulting as the base. I really like this idea. It was mentioned on flexcoders after I started working on a solution using DataGrid, but I think this way is definitely worth exploring. I haven’t played with the scheduling framework yet, but at first glance it seems like much of the work they did for that would carry over very well for a Gantt chart.

So like I said, I went with the DataGrid option. The basic idea is the same as on Andrew Trice’s post, I just went a little further. In my example you can manipulate the data in the chart. Each item is represented by a slider that allows you to adjust the starting point, the end point, and the percent complete for each task. To try this in the example just click on one of the items and the slider thumbs should appear.

Another cool thing this shows is some skinning and customization of the Slider component. To get these sliders looking like they do I had to make the Slider apply different skins to the first, second, and third thumbs. I also needed different highlighting skins for the two portions of the slider track. And you can drag the entire region (that’s something that came from a previous post about draggable sliders). Deep down those are just Slider components, but they look and act fairly differently.

So I’m not going to go into heavy duty explanation of how this works. And I didn’t comment the code up very much (if at all). It’s not complete by any means, no axis is shown, etc. This is sort of my first draft and if you want to download the source and figure it out for yourself, go for it.

The example below shows a gantt chart with my plans for world domination. There are two charts here with the same data, but they show different skinning options.

View the source.

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

Problem with Transparent PNGs in Flex using @Embed

This was posted to flexcoders today. Here’s the problem: we’ve got a transparent PNG that is loaded into a <mx:Image /> control. Normally this control handles PNG transparency just fine. However, someone posted an example of a problematic PNG. If you set the source of the Image control to use the URL for the PNG on the server, then the image loads fine with transparency. But if you try to embed the image using the @Embed syntax, then the transparency is ignored and an ugly background color shows up.

I don’t know really exactly where the problem lies. The Image component (which is really just a glorified SWFLoader) should load the exact same image whether it’s loading from a URL or an embedded asset. But it doesn’t, and the test case posted on flexcoders proves this. Now, whether there’s something weird about the image I have no idea. But the fact is that it should have transparency and using @Embed within an Image component breaks the transparency.

So here’s a solution. Basically what I did was extend the SWFLoader class and change part of the loadContent() method. To do this I had to make a copy of the SWFLoader class (I called it BaseSWFLoader) and change the needed methods to protected instead of private. Once I did that I was able to create a subclass that could override loadContent and act differently for embedded assets.

The approach I took was to get the ByteArray of the embedded asset, then load that ByteArray using the loadBytes method of the Loader class. When I tried loading the problematic embedded PNG using loadBytes, it magically loaded fine with the transparency.

There’s a trick here, which is to set the mimeType of the embedded asset. If you set the mimeType to application/octet-stream, then when it gets handled by the custom ByteArraySwfLoader class I created we can get access to the raw ByteArray of the embedded asset. This means we can pass the ByteArray to a Loader component, which will be able to handle it using the loadBytes() method. If you don’t set the mimeType of the embedded asset then you don’t get the ByteArray of the asset, instead you just get a Bitmap object.

The small example below shows the problematic PNG loaded using both the <Image /> control and my custom class. Both work fine if we’re loading via a URL. But if we’re loading by using the @Embed syntax then the normal Image component messes up the transparency.

View the source.

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

Horizontal Accordion Component for Flex

People have asked for an Accordion component that lays itself out horizontally instead of vertically. Looks like Scott Barnes had put one together back in 2005 that worked for Flex 1.5. Seeing as he’s now as Microsoft I’d say the chances of him porting it to Flex 2 are zip. Others seem to be trying to make this component as well. Well, here it is, an accordion component that cascades horizontally for Flex 2.

You use it just like the normal accordion component. The only difference is now you can use the “headerWidth” style instead of headerHeight to set the width of the tabs in CSS.

Making the component wasn’t that difficult, but it required a complete copy/paste of the Accordion component. If you look at the source you’ll see that I’ve made a class called AccordionBase. Basically this base class is a straight copy of the Accordion class from the framework but modified to allow it to be extended easier. That means I changed a bunch of properties and methods that were private to protected, so my subclasses could access them. Once I made these changes the only other thing I did to AccordionBase was remove the updateDisplayList and measure methods. These methods are defined in the subclasses, which are HAccordion and VAccordion. Each of those subclasses has slightly different code to do the layout and tweening. Ideally I would have been able to do this without making a new AccordionBase class that duplicated the code of Accordion, but this is another instance where a simple extension of a class doesn’t give you enough access to the parent class.

The one important thing to be aware of is that you MUST embed the font that you’ll be using for the text of the HAccordion’s headers. The component rotates the headers by 90 degrees, and if you rotate a text component then it will only work if you have the font embedded. See the source of the example MXML file to see how I did this, it’s simple, but if you don’t do it you’ll be wondering why the headers are all blank.

I packaged the component as a SWC. You can download the SWC and drop it into a Flex project. Download the SWC here. (281 K)

Here’s the full source of the component. And here’s the source of the example MXML file that makes the example below.

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

Even Better Scrollable Menus for Flex

Here’s an update to the Flex Scrollable Menu controls that I posted earlier today. Josh Tynjala made the point that he would rather have up and down arrows at the top and bottom of the menus to allow you to scroll without using a scrollbar on the side. Well, ok, ok, here you go. Now the menus can have either a vertical scrollbar on the side, rollover arrows on the top and bottom, or both! Yay!

Also, if you don’t specify a maxHeight for the controls, then the menus get sized as high as they can without going off the stage. So if a menu is too big it will size itself to as high as it can, and then start scrolling. If you specify the maxHeight attribute for the controls then the menu will try to size itself that high, but not higher. But again, if there’s not enough room on the stage then the menu won’t grow beyond the visible area. As far as I can figure, this is how menus should work.

So check it out and play with some of the options in the example. You can set both verticalScrollPolicy and a new property: arrowScrollPolicy. Both work the same way as you’d expect. arrowScrollPolicy controls the display of the up/down arrows just like the scrollbar is controlled. So you can set arrowScrollPolicy to ScrollPolicy.ON, ScrollPolicy.AUTO, and ScrollPolicy.OFF. If you turn both the arrows and the scrollbar on then you can scroll using either of them.

And again, full source is here.

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

Scrollable Menu Controls

As I was writing some stuff for the extended TabNavigator component that I’ve been working on (see some previous posts), I came across a need to use a PopUpMenuButton to list all the tabs, similar to how Firefox does this with the drop down list to the right of the tabs. This works great, except when there are a ton of tabs and the list gets really really long. Suddenly I realized that all the Menu controls in Flex have no option of adding a scrollbar to the menus. So if your menu is huge and goes off the stage, there’s nothing you can do about it and the menu items at the bottom are completely inaccessible.

mx.controls.Menu
So the complete inability to scroll a menu seemed a little weird to me, so I investigated and took a look into the mx.controls.Menu class. The answer to why the menus would never scroll is pretty obvious once you look at the code for the Menu control. The getter and setter for verticalScrollPolicy are these:


override public function get verticalScrollPolicy():String {
	return ScrollPolicy.OFF;
}

override public function set verticalScrollPolicy(value:String):void {
}

So if you were to try to set the verticalScrollPolicy of a Menu to ScrollPolicy.ON or ScrollPolicy.AUTO it wouldn’t do anything, and the scrollbars would remain off. There are a few other pieces in the code for Menu that don’t allow scrollbars, particularly in the configureScrollBars() and measure() methods.

So that’s no good if you want to allow scrollbars on your menus. The solution? An extension of mx.controls.Menu that overrides these problematic parts of the code. Basically I re-instituted the normal functionality for the getter and setter for verticalScrollPolicy, changed the configureScrollBars() method to actually configure the scrolling, and then modified measure() to take the scrollbars and new height restriction into account. Then we’ve got a new ScrollableMenu class that will allow you to set the maxHeight property. If the menu goes beyond maxHeight then the scrollbars are added, just like a normal scrolling control.

mx.controls.MenuBar
I also created a class that extended the MenuBar class, so it would use my new ScrollableMenu instead of the normal Menu when it created the Menus for the MenuBar. I was able to keep this extension fairly short, mostly just with an override of getMenuAt() and a private menu event listener.

So com.dougmccune.controls.ScrollableMenuBar lets you use the MenuBar control and specify a maxHeight, which will put a height limitation on the menus that popup when you click a menu item.

mx.controls.PopUpMenuButton
The PopUpMenuButton class was trickier. I initially tried to do a simple extension and get it to use the ScrollableMenu class instead of the normal Menu class, but this didn’t work so well. This was one of those cases (I’ve encountered this quite a bit) where the class you’re extending has private functions and variables that you need access to in order to accomplish your goals. I really didn’t need to make many changes to PopUpMenuButton, but because of the structure of the class I simply wasn’t able to make a clean extension.

So instead of extending PopUpMenuButton I had to copy/paste the entire class into a new class, and make the changes I needed. I’ve had to do this quite a few times to get custom components that I need. It’s obviously not ideal, you end up bloating your code base, but sometimes that’s the only option. But in the end we have a ScrollablePopUpMenuButton class that allows us to specify a maxHeight and that height will apply to all menus and submenus.

I’ve included the full source of all of these classes and the example below. I documented the code pretty well, so hopefully you can figure it out by taking a look. I wasn’t planning on uploading this one to Adobe Exchange, it doesn’t seem quite “componenty” enough. But if someone from Adobe thinks it belongs on the exchange then I’ll upload it, let me know in the comments.

View the source. UPDATE: See the next post for the current source of the component.

Here’s the example:

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

Vertical MenuBar Component

Someone on the Adobe Flex forum asked a question about being able to have vertical menus using a MenuBar component. The response from Peter Ent from Adobe was that no, Flex does not include a MenuBar component that can handle vertical menus, but feel free to make one yourself and post it <hint, hint>.

After I read that it felt like a challenge, so here’s the solution: a Vertical MenuBar component. It extends MenuBar and works the same way, except the Menu items are stacked vertically and the menus open up either to the left or to the right of the menu bar. I’ve included the full source, it uses two classes, one that’s an extension of mx.controls.MenuBar, and another one that’s an extension of mx.controls.menuClasses.MenuItemRenderer. You can specify whether you want the menu to open to the left or the right by using the new direction property of the new component.

I tried to document the code really well, so it should be fairly straightforward if you take a look. I managed to get around needing access to all the private methods of MenuBar by repositioning the menus after they are placed on the stage and are shown. The instant they’re shown they’re moved to the right position. The one caveat is that this breaks the openDuration style of the Menu. If openDuration is set to use a Tween to animate the Menu opening, then I was stuck with showing the Menu during the Tween in the original position, then it would jump to the new correct position after the Tween finished. So you would see the Menu jump around after it opened, which was no good. So now openDuration cannot be used with the Vertical MenuBar, but I figure that’s not a big deal.

View the source.

Here’s the example showing both the normal MenuBar component on the top, and then two versions of the Vertical MenuBar, one that opens to the right and one that opens to the left.

This movie requires Flash Player 9.

Standard