Not yet rated

Problem

Creating menus which extend beyond panel bounds in CS Extensions very often requires the use of a "NativeComboBox". NativeComboBox uses NativeMenu. When clicking on a NativeMenu, a button below the menu can have its state change incorrectly to the down state.

Solution

Subclass Button to fix the state.

Detailed explanation

When creating panels for the Creative Suite I very often use NativeComboBox. (I actually use a slight variation on the component which offers some additional functionality, but that's unimportant for this article.)

I discovered that when clicking on a NativeMenuItem, there seems to be some anomaly related to the click event which can change the state of a button below the click to the over state. The skin on the button remains the "over" skin until it is clicked. Mousing in and mousing out of the button does not help.

For clarity sake, I should explain that I am discussing Halo (Flex 3) Buttons and not Spark (Flex 4) Buttons. Controlling the state of Spark Buttons is much more straight-forward. However, CS Extensions for CS5 and CS5.5 are limited to Flex 3.

Looking around I could not find any documentation on how to control the internal state of a button. There are no public properties or methods for checking or changing the button state. The button state is not saved as a State either.

What to do?

mx_internal to the rescue!

Digging around in the source code of the Button component, I discovered that the state is saved as a variable called "phase" in the mx_internal namespace. There's a ButtonPhase class which has constants for "down", "over" and "up". With a little creative thinking, I came up with a solution of setting the phase to "up" on mouse out. (It should never be anything else if the mouse is not over the button.) I only set it conditionally to avoid adding unnecessary overhead.

Once I subclassed Button, it's just a matter of using NativeCompatibleButton instead of Button anywhere a NativeMenu can cover a button.

That's it!

Here's the full code for the class:

 

package components
{
    import flash.events.MouseEvent;
    
    import mx.controls.Button;
    import mx.core.mx_internal;
    use namespace mx_internal;
    
    public class NativeCompatibleButton extends Button
    {
        public function NativeCompatibleButton()
        {
            super();
            addEventListener(MouseEvent.MOUSE_OUT,setPhaseToUpPhase);
        }
       
        private function setPhaseToUpPhase(ev:MouseEvent):void
        {
            if(phase != "up"){
                phase = "up";
            }
        }
       
    }
}

+
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.

Report abuse

Related recipes