Sunday, April 5, 2009

Flash SimpleButton, and MOUSE_OVER and MOUSE_OUT not firing

Adobe Flash documentation is often worse than useless. Useless would be "tells us nothing we didn't already know". WORSE than useless is "tells us information that is NOT correct, causing us to waste time".

Their flash.display.SimpleButton is the culprit once again.

I was dynamically generating SimpleButton instances in ActionScript 3, and adding MOUSE_OVER and MOUSE_OUT event handlers.

But the event handlers were never firing.

I reviewed the documentation - the SimpleButton definitely supports the MOUSE_OVER and MOUSE_OUT events.

I tried adding the event handlers to the flash.text.TextField instances which formed the button states, but that didn't work either - the events simply never ever fired.

I finally figured out what's going wrong. It's that SimpleButton constructor once again.

Here's what the doco says (false info - worse than useless) about the SimpleButton constructor :

Any or all of the display objects that represent the various button states can be set as parameters in the constructor.

ANY OR ALL ... CAN BE. In other words, it is OPTIONAL to set the various states using the constructor.

In a previous blog post, I noted that, despite the CLAIM that the constructor arguments are optional, the first argument is actually MANDATORY.

If you don't specify the first argument, the button never transitions between states, even if you set the states later using the upState, overState etc properties.

But if you DO specify the first argument, the up-and-over animation works correctly.

That was from that previous blog post.

Well, the new lesson for today's blog post is that in fact ALL FOUR arguments to the constructor are MANDATORY if you wish to get MOUSE_OVER and MOUSE_OUT events from the SimpleButton.

It doesn't make sense, and it makes mockery of their (poor as too often the case) documentation, and in fact makes mockery of Adobe's ability to design an intuitive API, but it is the case.

The one saving grace is that we can specify the SAME DisplayObject for all four constructor arguments. e.g.

var sb:SimpleButton = new SimpleButton(MySprite, MySprite, MySprite, MySprite);

(And of course, the other way you can do it is subclass SimpleButton and set the upState, overState etc properties in your own constructor. Basically, by the end of the constructor, those values must be set.)



As a final note, I was just about to paste the simple test code I whipped up, to make it extremely easy for you to reproduce my test results, but as I did so, Adobe Flash suddenly died on me and completely disappeared from the taskbar without even its usual "Adobe Flash just died" popup message.

All I can say is that I am disgusted with Adobe Flash - not only is the documentation often worse than useless, but the program itself is fragile, and crashes on me usually more than once per work day.

And this is Flash CS4 - their latest and greatest...

4 comments:

giambo said...

And even more interesting:
if you set up a subclass SimpleButton, the MouseEvent.CLICK will never be fired on a remote server. Work around is to addEventListener a MouseEvent.MOUSE_UP to the subclass.

Anonymous said...

Thanks for posting this man. I ran into this issue as well. Gotta love Flash/Adobe, the champion of the blackbox.

Scott said...

I just started writing my first giant project in actionscript, and I am lucky I found your post. It's been over three years since you wrote it, but the problem is still there in Flash CS6. I was going crazy trying all sorts of variants, but it never occurred to me that would be the problem. I even noticed checking the SimpleButton's hitTestPoint for the mouse X/Y on the Stage's mouse events worked fine, just couldn't get the events for the SimpleButton itself.

Thanks again, you saved me some premature balding.

ISAWHIM said...

This, and the fact that only SOME of the actual mouse functions actually identify the "target" or "currentTarget", from "stage", is driving me up the wall. Trying to write a global mouse-management system, and some functions actually return names, some return null, some return main-1, some return ???. All being the same event, one would assume they operate the same. Well, here is to assumptions...

I don't even think they know what flash does anymore. They don't follow their own standards, or any-one else's standards. Yet, they wonder why they are plummeting in the computer world.

Flash is still just seems good for ads, novelty-buttons, and a few loose-apps. Time to retire flash and move on to better things.

That is what happens when you have no actual direction, and attempt to create one program to "do it all", then contradict yourself by separating that one app into multiple apps that don't do anything anyone wants. They are corporate AIR-heads. The result of programmers who don't listen to actual users, and only program for other programmers, who don't actually program anything with it.

Thanks for the write-up, you stopped me from balding too.