Simple monkey patch to fix ToolTipManager.toolTipClass
ToolTipManager.toolTipClass doesn't work in Flex 3.0 out of the box. While its intent of allowing you to specify a custom IToolTip implementation is great, ToolTipManagerImpl simply acts as if the property doesn't exist and instantiates an instance of ToolTip. Luckily, the fix is quite easy if you are willing to do a bit of monkey patching. You just have to make a slight modification to the createToolTip() method, making it look like the following:
errorTipBorderStyle:String = null,
context:IUIComponent = null):IToolTip
{
// ***** USE THE PROPERTY! *****
var toolTip:IToolTip = new ToolTipManager.toolTipClass();
var sm:ISystemManager = context ?
context.systemManager :
ApplicationGlobals.application.systemManager;
sm.toolTipChildren.addChild(UIComponent(toolTip));
if (errorTipBorderStyle)
{
UIComponent(toolTip).setStyle("styleName", "errorTip");
UIComponent(toolTip).setStyle("borderStyle", errorTipBorderStyle);
}
toolTip.text = text;
sizeTip(toolTip);
toolTip.move(x, y);
// Ensure that tip is on screen?
// Should x and y for error tip be tip of pointy border?
// show effect?
return toolTip;
}
Here is a diff of the base and updated classes.
As an aside, an easier fix is said to exist here, but it doesn't seem to work when calling ToolTipManager.createToolTip() directly, which is what I needed to do. If you are using toolTips normally by just setting the toolTip property I would recommend trying Peter's fix first.
I would also like to go on record that I hate the *Impl naming convention. Despite what Theo says, I like my interfaces with I's. *Impl just seems kludgy and redundant, and it reminds me of AS2.
DepthToggleButtonBar - a simple custom component example
I recently needed a component very similar to the ToggleButtonBar that is provided by Flex. The seemingly minor difference was that the selected button needed to be placed above the others in terms of z-index. I assumed I would be able to subclass ToggleButtonBar and tweak it to my needs but ran into a problem: the buttons are arranged horizontally/vertically according to their child index. This meant even though I could change z-order when a button was clicked, it was then moved to the right end of the row of buttons on the next render update.
In response I created my own component that would do exactly what I needed and have decided to post the base functionality here. I have added copious amounts of comments to the code so I won't bother trying to explain it here. Questions and comments go in the form below. :)
Enjoy!
Yes, I know Astro is out. Seriously.
The echo chamber that is http://feeds.adobe.com/ is seriously out of control. This morning Google Reader told me there were 110 unread items from that site. Having already seen the announcement about Astro (AXNA is not my only source of news, shocker!), I knew most of the items would be on that topic. As it turns out, 35 of those 110 items (thirty freakin' five!) were simply repeated headlines, bullet points and OMFGWTFITSOUTKTHXBAI!!!!! posts. Note I am not counting Adobe employees and people who actually provided some original discussion and/or questions in this number.
Really people, if you have nothing to add then why post? Do you really think you have readers that don't also read the major sources, like Adobe Labs itself and the various Adobe employee blogs? I just don't get it.
This rant brought to you by day #3 of intolerable neck pain and my naturally sarcastic nature.
PS - Flash Player 10 Beta is out!!!!! Seriously.
Open Web: Fifteen year old third grader?
I don't really want to get fully involved in the discussion being had by Ryan Stewart, Asa Dotzler and Simeon Bateman. However, in reading through each argument a few things Asa said struck me as particularly indicative of the fact that he, and I suppose maybe Mozilla as a whole, simply don't get it. I am admittedly cherry picking here, but I couldn't resist pulling out a few quotes.
Open is developing the protocols and specifications in a co-operative and participatory environment and then competing on implementations.
Replace "Open is" with "The colossal headache that is developing consistent experiences that are cross browser/platform and engaging to users is thanks to" and you've got a true statement. I use Firefox as my primary browser and think overall its a great application but unfortunately, telling a client their new site looks great in Firefox and like garbage in IE won't exactly result in a lucrative career. Developing for "competing implementations" sucks, and its a large part of why Flash Player is so widely embraced and successful.
If I was in Adobe's shoes, I'd give everything away, all of it. Hell, I'd pay people to develop on the Adobe platform and I'd encourage dozens of competing implementations of my platform across every type of device imaginable because, in the end, it'd be my platform and I'd decide how and when it evolved and to what ends.
See above for my thoughts on competing implementations.
So, all I can do in this battle for the future of the Web is to advocate for advances in real open Web standards from groups like ECMA, W3C, and WHATWG. It may be a bit slower to market, (hopefully not too much slower,)...
A bit slower? Seriously? Just a bit? Far as I can tell HTML 4.01 was finalized in December of 1999. Nineteen ninety freakin' nine. Best I can tell the latest Flash Player back then was version 4. So in the 9 YEARS we've been stuck with HTML 4 there have been 5 full version releases of Flash Player. If thats a bit then I am just a bit shy of being a billionaire. Yes, Firefox has had a few releases in that time but it wasn't adding any new capabilities, just improving its implementation of the same old spec.
So be patient everyone, for by 2011 you will almost certainly have a finalized HTML 5 spec and, not only that, your choice of no less than 4 major implementations of it to choose from!
Is the Open Screen Project a good thing?
Disclaimer
OK, maybe I am on crazy pills since 98% of the reactions I've seen thus far have been positive, but I have some pretty serious reservations about this whole thing. I make a living developing for the Flash Platform via Flex, and have a great time doing it, so I am extremely invested (in most every sense of the word) in the success of the platform. I also have no business training or education and have only an outsider's view of Adobe and the decisions the company makes. As such its entirely possible that some of what I say here may be completely wrong. If that is the case I apologize in advance and welcome any corrections.
Flash Players everywhere!
So one of the main benefits the project aims to create/claims to enable is the proliferation of Flash Player on a multitude of devices. The enabler of that proliferation, according to Adobe and others, is the removal of licensing fees and terms. Now when they say devices, they mean everything from cell phones to those fancy internet-enabled refrigerators nobody wants. In my opinion though, cell phones and UMPCs are what most people think of when the term "device" is used (and is what I mean by the term for the remainder of this article) and they easily represent the area with the largest potential for growth and impact.
But was licensing really what prevented Flash Player (the real deal, not Lite) from being found on devices to and fro? Up until Open Screen was announced I had never even heard such a thing suggested. The real reason, which seems suspiciously absent from discussion today, is that Flash Player is simply too memory and power intensive to run on most devices. Note this is absolutely not a knock against Flash Player, today's devices are simply not very powerful and/or efficient. Maybe its just the initial excitement of the project but I find the complete lack of discussion of this major engineering hurdle perplexing.
Further evidence (in my mind) that its an engineering issue rather than a licensing issue is evident by looking at the partners listed on the project home page. Do you really think companies like Nokia, Samsung and Sony have any problem licensing technology they think will make their handsets more valuable? They're not exactly short on cash, so if they find it valuable now they probably found it valuable a year ago. Yes, Adobe will be providing porting APIs which will help device manufacturers get the software running on their device, but thats not a silver bullet. Those porting APIs will be useless until there is a version of the player that can run in the first place within the power and memory constraints the device provides. Yes, I know about Tamarin-Tracing but everything I have read in regards to that points to it being a long way from production ready.
Financial aspects
This section is pure speculation but worth including I think. I also wonder about the revenue stream the licensing costs provided and how, if at all, Adobe plans on replacing that. I could be wrong but I thought I remembered hearing it was a pretty sizable chunk of change. Between this announcement and the proposed opening of the FLA format recently announced, what props up the Flash Platform for Adobe from a financial perspective? The only things that come to mind are the Flash IDE, Flex Builder and I suppose licensing/infrastructure fees for Flash Cast, as well as LCDS and FMS licenses. I have a hard time believing LCDS and FMS make a ton of money above and beyond what they cost to produce and support, and if you spend any significant time using Flex Builder you know it could be easily displaced as the premiere Flex IDE should another company decide to devote the resources to creating a true competitor. (There are high hopes for the forthcoming Flex support in IntelliJ.) That leaves Flash Cast, which I have no idea about, and the Flash IDE. Who knows, maybe the Flash IDE and/or Creative Suite makes enough to support the Flash side but it seems odd to eliminate a source of revenue generated by the platform itself.
Which Player?
While the persisting engineering challenge is a major hurdle not to be overlooked, my concern regarding it is dwarfed by my concerns about something else. That something else is 'the F word'. Fragmentation. Myself and countless other developers were drawn to Flash largely because of its true write once run anywhere capabilities. I can honestly say I would have taken a completely different career path if all development suffered from the hell that is HTML/CSS/JS development when it comes to consistency across browsers and platforms. Flash Player undoubtedly owes a significant portion of its ubiquity and success to that consistency.
Until today that consistency was enforced by prohibiting the creation of SWF playback tools by anyone who had gained access to the file spec. Today that restriction was lifted and anyone can view the spec and do with it as they please. That makes me very nervous. Make no mistake about it, even with full access to the spec creating a SWF player would be no small task. Hmmm, are there any organizations out there with technical skills and significant resources and anything to gain by creating their own player? I think I could name a few.
I shudder at the thought of trying to troubleshoot my Flex 5 app for not only Flash Player 11, but also Silverlight 3 (now with SWF playback!), Apple SWF Player 1.0, Sun SWF Player .8 and the NBC Universal Music and SWF Engine. Not to mention playing family tech support to figure out if my dad has the right player for what he is trying to do. Ick.
Bad people
I am not one for conspiracy theories, but allow me to put on my tin foil hat for a moment. What is to stop any ill intentioned group from creating a SWF player with some not so nice 'capabilities'? It would be possible to create and get users to install a player that looks and acts just like Adobe Flash Player, even has the same context menu and is indistinguishable in virtually every way, except this player comes with a handy dandy keystroke logger. And a nice little phone home feature that sends back your entries and reports every site you visit that contains a SWF. Wouldn't that be swell?
Or maybe their player eliminates the context menu and crossdomain restrictions altogether and immediately enables every security issue those features are meant to address. The list of potential abuses is almost endless. The only thing really keeping this from happening is some spare time and technical know-how and/or deep pockets. Sadly, if possession of those was rare we would not have the malware and phishing problems we do today.
Take a deep breath
What do you think? Am I crazy? Do any of these things concern you? For everyone's benefit I hope I am just being paranoid, but I will be very surprised if we don't see at least some of these problems in the not-so-distant future.
You don’t need MXNA if you use my reading list
Wow, almost two months of nothing and then two posts in one day, crazy. Anyhow, I'm not missing MXNA a bit, mostly because I obsessively add blogs to Google Reader. If I read one good post on a site and think they might have good info in the future I add it. So here is my OPML file that you should be able to import into any feed reader and instantly have access to lots of good info. I think I have somewhere around 100 sites in there devoted to Flash/Flex so if thats your bag check it out. Don't worry about the echo chamber though, I avoid sites that "report" every breaking story like its news to anyone but my mom. (Microsoft made a bid for Yahoo!?!? No way, when?!?!) There are also a few non-Flash Platform related items in there but they are things any self respecting developer should be reading anyhow, like Dilbert and Joel Spolsky.
Enjoy!
Solid HRule/VRule in Flex
This was completely non-obvious to me so figured I would blog it. To create a rule more than one pixel thick of a solid color use this format:
strokeWidth="4"
strokeColor="#1278A7"
shadowColor="#1278A7"
opaqueBackground="#1278A7" />
opaqueBackground is the key attribute since by default (and counter intuitively) rules are actually borders around a transparent rectangle.
flexmdi sans MXML
Every now and then I come across a request of how to use FlexMDI using only ActionScript. Its completely straightforward but I have finally gotten around to getting an example up. The first code snippet shows how to do this while still utilizing MDICanvas for some of the convenience it provides.
import flexmdi.containers.MDIWindow;
import flexmdi.effects.effectsLib.MDIVistaEffects;
private function init():void
{
var mdic:MDICanvas = new MDICanvas();
mdic.percentWidth = mdic.percentHeight = 100;
mdic.effects = new MDIVistaEffects();
var win1:MDIWindow = new MDIWindow();
win1.title = "First Window";
win1.width = 300;
win1.height = 200;
mdic.addChild( win1 );
var win2:MDIWindow = new MDIWindow();
win2.title = "Second Window";
win2.width = 300;
win2.height = 200;
win2.x = 325;
win2.y = 50;
mdic.addChild( win2 );
var btn:Button = new Button();
btn.label = "Awesome Button";
win2.addChild( btn );
addChild( mdic );
}
This next example shows how to turn a basic Canvas component into the container for an MDI implementation.
import flexmdi.containers.MDIWindow;
import flexmdi.effects.effectsLib.MDIVistaEffects;
import flexmdi.managers.MDIManager;
import mx.containers.Canvas;
private function init():void
{
var canvas:Canvas = new Canvas()
canvas.percentWidth = canvas.percentHeight = 100;
var mgr:MDIManager = new MDIManager( canvas, new MDIVistaEffects() );
var win1:MDIWindow = new MDIWindow();
mgr.add( win1 );
win1.title = "First Window";
win1.width = 300;
win1.height = 200;
win1.x = win1.y = 10;
var win2:MDIWindow = new MDIWindow();
mgr.add( win2 );
win2.title = "Second Window";
win2.width = 300;
win2.height = 200;
win2.x = 350;
win2.y = 100;
var btn:Button = new Button();
btn.label = "Awesome Button";
win2.addChild( btn );
addChild( canvas );
}
Hopefully this clears up some of the uncertainty around how to use FlexMDI without our good friend MXML but feel free to ask questions in the comments.
flexmdi is now part of flexlib
This announcement got a bit lost in the shuffle at 360|Flex so I wanted to officially get it on the record. flexmdi is now part of the most popular Flex component library around and can be found in the flexlib.mdi package. We considered offering the library to flexlib when we first created it but decided to release independently and gauge feedback first. We thought maybe we'd get an invite to join flexlib and about 3 days after launch that's exactly what happened. Yea, yea, that was about 6 months ago, I know. Well, we finally got around to it and flexlib.mdi is our new home. While flexmdi has done very well on its own and its been downloaded about 8,000 times, joining flexlib will give the library even more exposure and chances to be seen and used. I think all told flexlib has been downloaded about 30,000 60,000 times.
So thats about it, just wanted to make sure those who haven't heard did and know what is going on. All future development will happen in the flexlib repository and any future bug and/or enhan cement requests should be submitted on that site. We will be porting the existing isues list over, eventually. :)
Creating bindable, calculated read-only properties in Flex
Binding to read-only properties in Flex takes a bit more work than one might think at first glance. There are two basic types of read-only properties in Flex: "variable backed" and "calculated". Can you guess which one we're going to discuss here?
Lets start by clarifying exactly what we mean by read-only property. The most basic description is when you have a getter but no setter:
The variable backed version is when the getter is just a gatekeeper for a private variable:
public function get someValue():Number
{
return _someValue;
}
The calculated version is a bit more complex and is generally either a combination of values like first name and last name or a value that requires calculation. The example we'll use here is a totalTime property of a Playlist. The totalTime is calculated by adding together the duration of all songs in the playlist at any given time.
OK, how?
By default you will get a warning telling you that the binding on a read-only property will be ignored (and whatever you've bound to it will indeed not receive any updates). The first part of enabling the bindings involves using metadata. Everybody knows [Bindable], but what we're looking for is [Bindable(event="eventName")]. That will essentially tell the compiler to dispatch a PropertyChangeEvent for the property (which is how binding works) any time an event of type "eventName" is fired. That brings us to the next step of firing the event. In our scenario of a calculated read-only property this needs to happen when one/any of our inputs changes.
Going back to the playlist example, a good time to let everyone know totalTime has changed is when a song is added. For the sake of simplicity that is the only scenario this example covers. I won't bother talking through the code in the example because it is very straightforward.
View the example and view the source and you'll see this is all very simple. I have included the classes generated by the compiler as well in case anyone wants to dig around. The magic seems to be injected from _CalculatedBindableReadOnlyWatcherSetupUtil.as but I won't claim to have a very solid understanding of how that all works.
I hope this will shed some light for somebody out there and maybe even come in handy if you're stuck. Binding to variable backed read-only properties has been covered by numerous other people and I would recommend learning about that as well. Enjoy!

