I admit, this post will be useless for most readers of this blog. But if you happen to be an Actionscript programmer… I had a minor epiphany today from which you might benefit.
Since I started writing AS3 code, I’ve generally viewed the
mouseEnabled properties of the
InteractiveObject class (and by extension the
Sprite class) as relatively superfluous. They existed as little more than a recourse for when something accidentally got ‘in between’ the mouse and a button that needed to be pressed. And in a sense that is true. But I realized today that those crafty AS3 creators had bestowed upon me a much more substantial tool than I’d first realized.
Fundamentally, these two properties are straightforward. Setting a Sprite’s
mouseEnabled property to
false tells that Sprite to not bother interacting with the mouse. In other words, to stop dispatching MouseEvents such as
MouseEvent.CLICK. Likewise, setting a Sprite’s
mouseChildren property to
false tells the children of that Sprite to stop dispatching MouseEvents. By default, both properties are set to
The magic comes by virtue of the fact that these two properties work independently of each other. If a Sprite has children, setting that Sprite’s
false does not prevent the Sprite’s children from dispatching MouseEvents. Similarly, setting the Sprite’s
false doesn’t prevent the sprite itself from dispatching MouseEvents. Why is this cool? Let me count the reasons:
- Sprite ‘flattening’. It used to drive me nuts that that a button made of multiple sub-elements (label, hilight, border, icon, etc) would have an indeterminate MouseEvent ‘originator’. That is, the
targetproperty of the MouseEvent would be ‘label’ or ‘highlight’ or whatever depending on the exact pixel over which the mouse rested, rather than simply ‘myButton’. I found myself putting invisible ‘mousetrap’ layers in my buttons to sit on top of everything to fix this. It turns out I don’t need to. By setting
myButton.mouseChildren = falseall the button parts become a single unit, collectively dispatching MouseEvents with a
- Group disabling. Need to disable a whole group of buttons? Make them siblings and set the parent Sprite’s
- Event-bubbling simplification. By setting a container Sprite’s
mouseEnabled = falsebut leaving
mouseChildren = true, you prevent the ‘middleman’ from sending unnecessary MouseEvents to high-level MouseEvent handlers. Imagine a calculator, with multiple keys, a display screen, a surrounding ‘case’, a nice little Texas Instruments logo, whatever. If I add a
MouseEvent.CLICKlistener to the high-level calculator object, I will receive all of the various key clicks, but I will also receive events from the other child elements… the display, the case, the logo. Even if I set those elements to
mouseEnabled = false, the calculator Sprite itself will still trigger its own MouseEvents when I roll over them. By following up with
calculator.mouseEnabled = false, the high-level listener will now only receive events from the children that matter, and will not be encumbered with ‘false positives’.
Given this greater understanding, I almost wonder why the AS3 creators chose to set the default of
true. After all… aren’t there generally far more ‘passive’ display objects on the stage than interactive ones? I’m sure they had a reason, and it’s probably one that I could find by Googling around a bit… but enough is enough. Hardcore geek session over.