Flash SimpleButton sticks in over state?
I'm working on a Flash project using ActionScript 3.
Our interface switches between different modes by adding and removing the direct children of the main stage--we call these scenes.
The problem I've encountered is this: One of these scenes has a SimpleButton (flash.display.SimpleButton) with distinct up and over states. When I mouseover a button, it goes to the over state as expected. But if the application automatically switches to a new scene (in this case, a video finishes and the app moves on) and then the user navigates back (causing the original scene to be re-added), the button stays in the over state until I mouse back in and then out again. I'd like to be able to force that button back into its up state.
I've tried setting b.overState = b.upState, but then there's no appearance change on subsequent roll开发者_C百科overs. I've also tried dispatching a ROLL_OUT event to the button object, but that doesn't do anything either.
Any ideas other than implementing something from scratch that exposes a way to force a state change?
here is what I had to do:
// store ref to normal over state
var overState = myBtn.overState;
// since we cant change the state, change the over state's asset to the up state
myBtn.overState = myBtn.upState;
// since we want the state to change on mouse over, reset the overstate once it rolled over again
myBtn.addEventListener(MouseEvent.MOUSE_OVER, function(e){
myBtn.overState = overState;
})
it's not too pretty, but it works. in my case, i fire this swapping logic when i render the buttons parent to the display list. if you are using scene's you could probably do it once the scene changes back to the one with your button.
I have the same problem: Panel has buttons. The click button switches window. When panel restored, it has the button in wrong state. I can't fix my problem with your issue because panel has many different buttons.
Bug: ROLL_OUT happens AFTER(!) my panel removed from stage. This is the real reason why the button can't normal restored state.
Bug fix (work around): You should generate ROLL_OUT event BEFORE(!) parent object will be removed from stage. The easy way to do this is a create empty sprite and overlap panel, such as:
Step 1:
var overlay:Sprite = new Sprite();
overlay.graphics.beginFill( 0x000000, .5 );
overlay.graphics.drawRect( 0, 0, _sprite.width, _sprite.height );
overlay.graphics.endFill();
overlay.x = _sprite.x;
overlay.y = _sprite.y;
overlay.name = "TRICK";
addChild(overlay); // The top element overlay is override the buttons and it’s automatically generated event ROLL_OUT
Step 2: If window with panel and buttons is restored then remove overlay:
var overlay:Sprite = this.getChildByName("TRICK") as Sprite;
if (overlay) removeChild(overlay);
I had the same problem with some menus, each menu was removed from the display list before the new one was added.
After many attempts to find a work around the best one I found was to keep it them on the display list and just set their visibility to false.
function setMenu(newMenu:Sprite = null):void
{
menuA.visible = menuB.visible = menuC.visible = false;
if(newMenu)
{
newMenu.visible = true;
}
}
Use MOUSE_OVER
and MOUSE_OUT
instead.
ROLL_OVER
and ROLL_OUT
do not propagate to child objects.
I would try to replace the simpleButton
with a MovieClip
, but if you want a real solution you should write a bug report to Adobe.
I had this problem, and after reading gthmb's answer this is what I did. I set hitTestState to the same as overState during init (previously it was the same as upState), and:
public static function ResetButton(b:SimpleButton):void
{
b.overState = b.upState;
b.addEventListener(MouseEvent.MOUSE_OVER, RestoreButton);
}
private static function RestoreButton(e:Event):void
{
e.target.removeEventListener(MouseEvent.MOUSE_OVER, RestoreButton);
e.target.overState = e.target.hitTestState;
}
So for each problematic button, just add ResetButton(e.target as SimpleButton);
in their CLICK event listener. Don't use it on every button though, because then when you click it, if the scene doesn't change the button won't go back to the over state but to the up state. Apply it to one of the ordinary buttons if you don't know what I mean.
This is easily fixed if you leave the SimpleButton on the stage but you set visible = false; However if you want to remove it from the stage and make sure the button has the event mouse_out dispatched on it here is how I suggest you do it:
To set the SimpleButton back to the mouse out state I suggest a few seconds later assuming the user house moused out, you may remove it from the stage, see the following example:
_removeTimer = new Timer(2000);
_removeTimer.addEventListener(TimerEvent.TIMER, _onRemove);
function _onClick(e:MouseEvent):void{
e.stopPropagation();
//hide button for now
_button.visible = false;
//move button to trigger mouse event
_button.x = 0;
_button.y = 0;
e.updateAfterEvent();
e.stopPropagation();
//set timer to remove the button later
_removeTimer.start();
}
function _onRemove(e:Event):void{
_removeTimer.stop();
_button.parent.removeChild(_button);
//reset button to original coordinates
_button.x = 100;
_button.y = 300;
}
精彩评论