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
Flex/Flash/Actionscript

The Quest for the Perfect Tab Navigator – Part 2

Here’s my progress on coming up with a TabNavigator component with all the features I’ve heard people talking about.

  1. Drag the tabs to re-order them. An indicator appears showing you where the tabs will be dropped. You can drop tabs before or after any other tab currently in the list
  2. Closable tabs. Click the close icon on each tab to remove it.
  3. List of tabs in a drop-down menu on the right. I’ve changed it now so the menu won’t go off the screen. It adds a scrollbar to the menu if it gets too long.
  4. If you don’t specify a tabWidth, the tabs are all at their own default widths.
  5. If there are too many tabs to fit the component first tries to squeeze the tabs in by making them smaller. You can set minTabWidth, which specifies the smallest that the tabs are allowed to be squeezed down to. If the tabs can’t be squeezed more then scrolling occurs (next point)
  6. Scrollable tabs. If the number of tabs is too many to fit, then arrow icons appear on the left and right side that allow you to scroll through all available tabs.

There are some definite bugs, especially when it comes to trying to set tabWidth and minTabWidth. Once I upload the source in the next day or so maybe someone else can figure it out.

So that’s pretty much where I’m at. Hopefully I’ll post the code tomorrow once I get around to cleaning it up a tiny bit more. Here’s the example of the current component. If you’ve got any more feature requests just post them in the comments and I’ll see if I can include them. Cool.

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

The Quest for the Perfect TabNavigator

[UPDATE: See Part 2 for the current component]

There’s been some discussion on flexcoders about a better TabNavigator component. And a few people have done some good stuff expanding on the original TabNavigator in the Flex framework. I figured I’d play around and try to add a little to the current TabNavigator modifications that are floating around.

First, a few references. Here’s a TabNavigator with draggable tabs that was posted on a blog called code zen. I used this as my starting point (well, actually I started from scratch, then realized this was already out there). The customized TabNavigator component there is pretty good. So I grabbed that, cleaned up a bit of the re-ordering of tabs stuff, made a few other tweaks, and then added some functionality of my own.

The demo’s below. Basically this allows you to add and remove tabs, drag tabs, but the cool part about what I added is the scrolling of the tabs. If the tabs get too long they do sort of what Firefox does, which is put buttons with left and right arrows on the sides of the tabs and allow you to scroll through them. I also added a drop-down button to the right edge that lets you select any of the tabs from a list, again a la Firefox.

I know Jason from Flexible Experiments has said he’s about to release the same component with the source. So his might come out in the next few days and make mine irrelevant.

I’ll release the source of my stuff in a day or two, after I clean it up a bit. Like I said, I used the code off of the code zen blog as my base, and I’m not in any way trying to steal that and claim it as my own. I’ll pubish the source of all my additions, and hopefully everyone can work together to make a TabNavigator that finally meets everyone’s demands. I figure between what’s already out there, whatever’s coming from Flexible Experiments, and anything that I included that’s not in the others, we’ll be able to get a pretty solid TabNavigator.

So here’s the demo. Try adding a bunch of tabs and see what happens when you add too many to display at once. Try re-ordering the tabs by dragging them. See the pretty little indicator arrow? ooh aah…

This movie requires Flash Player 9.

Standard
Flex/Flash/Actionscript

Draggable Slider Component for Flex

This is a Flex component that adds a draggable bar between two slider thumbs. This is very similar to the “Dual Slider Component” developed by Brendan Meutzner that has been on Flex Exchange for a while now. I’m posting my version because 1) I created it a while ago without realizing there was a similar one out there already and 2) mine works differently by placing the draggable portion directly between the thumbs of the slider on the track.

It’s a simple component, basically nothing more than the VSlider or HSlider that’s included in the Flex Framework, slightly modified for my purposes. If you look at the source you’ll see that the bulk of the component is Slider.as, which is a direct copy of the mx.controls.sliderClasses.Slider class that was included in the framework (upgraded to use the 2.0.1 version). Slider.as was copied completely, and then I added a few things to make it draw an invisible draggable region between the two thumbs. This is an example of something that ideally should have been done by extending the Slider class, but since I needed to access some of the private drawing and child creation methods, I had to copy/paste all the code and make a duplicate class.

Usage is simple, just use it as you would the VSlider or HSlider components. You need to specify a skin for drawing the highlight track. The default halo skin doesn’t work very well (it draws a line around the border of the draggable region). I’ve included two skins for the draggable part, each are shown below in the example and are included in the source code.

View the source.

This movie requires Flash Player 9.

You can download the source by using the link above, or you can also download the compiled SWC and drop it into your Flex project. This has the benefit that it will give you nice icons in the Components panel and it will show the previews of the components on the stage in Flex Builder.

Download the SWC: SliderComponent.swc (289 K)

Standard
Flex/Flash/Actionscript

How to load animated GIFs using Adobe Flex 2.0

UPDATE: The AnimatedGifLoader component is no longer for sale.

There are some open-source alternatives to load animated gifs in Flash/Flex projects. Please see the following links:
http://www.bytearray.org/?p=95
http://labs.flexcoders.nl/2007/08/30/another-bytearray-fxc-mixfxcloader/

This post is a brief tutorial on how to use the Animated Gif Loader component that I have developed for Adobe Flex. The component is a commercial component available for purchase. You can try the component out before you buy it, however, by downloading the demo version.

Loading a gif from a URL
Using this component is as easy as using the or components that come with the Flex Framework. All you have to do is add a line to your MXML code and specify the source attribute of the component. This tells the component which file (or embedded asset, more on that later) to load.

Here’s an example line of MXML that would get inserted into your Flex app:

That’s all it takes to get a simple animated gif playing in your Flex app. And what’s sweet is that the component works exactly like the SWFLoader component, so you get access to every method and property that you would from SWFLoader (such as scaleContent and maintainAspectRatio).

Embedded assets
The component also works with embedded assets in your SWF. See this quickstart article about embedding assets using Flex. Just like you can embed still images into your Flex app and reference the embedded file, you can do the same thing with animated GIFs.

The caveat is that you must specify the mime-type of the asset as “application/octet-stream”. So the tag to load an animated GIF as an embedded asset would be like this:



or if you’re using a
P.S. Hey Brendan, how about those awesome waving flags?

OK, cool, so loading animated GIFs is easy. Read more about the Animated Gif Loader component at my previous post: AnimatedGifLoader – New Flex Component (or just scroll down if you’re on the same page).

Standard
Flex/Flash/Actionscript

AnimatedGifLoader – New Flex Component

UPDATE: The AnimatedGifLoader component is no longer for sale.

There are some open-source alternatives to load animated gifs in Flash/Flex projects. Please see the following links:
http://www.bytearray.org/?p=95
http://labs.flexcoders.nl/2007/08/30/another-bytearray-fxc-mixfxcloader/

Problem: Flex doesn’t let you play animated GIFs.

Answer: AnimatedGifLoader! A Flex component you can drop straight into your MXML code and use just like the SWFLoader component included in the Flex Framework.

There has been some discussion on flexcoders regarding the inability of Flex to dynamically load animated GIF files. The basic answer is that no, you can’t really load animated GIFs. The more complicated answer is that there are some hacked-together workarounds involving IFrames. The semi-official response from Adobe is to make you convert your animated gifs to SWFs using Flash. Others have mentioned that they use some server-side magic to do the GIF to SWF conversion on the fly.

So since all this seemed far too silly to me, I created a component that lets you load animated GIFs.

What is the component?

It’s basically an enhanced SWFLoader component. It does everything the normal SWFLoader does, except it also loads animated GIFs. It’s based off the SWFLoader, but since I had to overwirte a bunch of private methods and things I couldn’t simply extend SWFLoader. You get a couple new methods and properties that weren’t included in SWFLoader.

New Methods:

  • play() — Plays the animation if it’s stopped.
  • pause() — Pauses the animation on the current frame.

New Properties:

  • autoPlay — A Boolean to indicate whether the animation should start playing immediately. If false, the animation will load and pause on the first frame. Read-write.
  • playing — A read-write Boolean that tells you if the animation is playing. If you set this via Actionscript it will either play or pause the movie. Bindable.
  • currentFrame — A read-only Number that tells you what frame the animation is on. Bindable.
  • delay — An optional Number to allow you to specify the delay in milliseconds between frames. If left unset this will use the delays between each frame that are specified within the GIF file

Other than that it’s just like SWFLoader. You specify the source attribute and it loads the GIF. You can use it inline in MXML or with Actionscript.

Examples

Here’s an example of loading an animated GIF using the AnimatedGifLoader component, compared with the normal SWFLoader component. You can see that the AnimatedGifLoader actually plays the animation and gives you some control over the playback. The SWFLoader on the right loads the same file, but it only displays the first frame. You can view the source of this example (doesn’t show you the source of the component, just the source of the example and how to use the component).

This movie requires Flash Player 9.

So that’s that. I’m infusing web 2.0 with some old school love. Bring those annoying GIF animations back into style!

Argh! Why isn’t this open source?

I know people are going to ask why I don’t just release the source code of the component and give it away as a benefit to the community. You can pick whichever answer you like from the list below (or make up a different one if it makes you feel better).

  1. I’m a greedy douche.
  2. I’ve been so cultivated by American capitalism that the only way I measure my self-worth is through financial means.
  3. I’m simply curious if people will actually pay for something a kid like me cooks up.

I’d like to think the real answer leans most towards #3, but who knows, maybe it’s closer to #1.

Standard
Uncategorized

Hey! It’s Another Flex Blog!

Yup, another blog about Adobe Flex. I’ll mostly focus on Flex work that I do, experiments, custom component development, yadda yadda. I might throw in some observations about San Francisco here and there.

About me

I’m 24 or 25, depending on when you read this. I live in the Mission District in San Francisco. I work at Stanford University (shout out to all who ride Caltrain). I’ve been working with Flex for a while now, whenever Flex 1.5 was first released. I’ve got a few mid to large size Flex projects under my belt. I like mangos. I’m pretty much the most web 2.0 person I know.

Standard