Source and a Fire component for Flex will be published when I get the time, but here’s a fun example.
Author Archives: Doug
I’m a Flex Machine! (according to my business card)
I just made myself the most ridiculous business card ever. I am now officialy a Flex Machine, James Brown is rolling in his grave. If you’ve never made yourself a business card, I highly recommend it.
Here’s the card design:
Now you’re probably thinking to yourself: “No way, that’s just a joke, you’d be insane to actually make that card and give it to anyone.” You underestimate my ridiculousness.
So find me at 360Flex and take some of these off my hands. And I openly challenge anyone to show me a more ridiculous Web 2.0 business card.
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:
- FishEye component from Ely Greenfield
- Custom modifications to add the bouncing functionality to the icons
- Reflection component from Ben Stucki
- Distortion effects from Alex Uhlmann
- TreeMap component from Josh Tynjala
Add them all together and this is what you get:
[Or launch it in it’s own window: here’s the link]
Source for this demo isn’t released yet, I put it together quickly, so it’s not quite up to my own standards.
Announcing FlexLib – open source Flex component library
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!
I am 788961937573 milliseconds old
var i:* = 24;
var now:Date = new Date();
var bday:Date = new Date(1982, 1, 16);
if(now.month == bday.month && now.date == bday.date) {
i = now.fullYear - bday.fullYear;
trace("Happy " + i + "th birthday to me");
}
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]
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.
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.
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.
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.