Flash中的模态窗口

时间:2009-07-09 17:24:34

标签: flash actionscript-3

简短版:

在Flash(AS3)中编程模态窗口是否容易/可行/可行?是否有内置功能?

长版:

我正在开发Flash小部件(在AS3中),我希望能够以模态方式显示影片剪辑。基本上,我需要在wieget中有一个简单的模态窗口。到目前为止,我了解到我需要自己实现“模态”(在AS3中)。之前版本的Flash曾经存在过一些东西,而Flex中有一些东西,但我没有使用Flax,我不确定它涉及到什么。

我自己编写了它,没有任何深入的计划,很快就遇到了一些问题。似乎问题的根源在于我无法将注意力集中在影片剪辑上(或者精确地称为InteractiveObject)。我在处理KEY_FOCUS_CHANGEMOUSE_FOCUS_CHANGE事件的同时试图防止失去焦点FocusEvent.preventDefault()。但我仍然设法通过鼠标点击失去焦点。甚至更奇怪的是,当我使用Stage.focus属性强制焦点时,我的影片剪辑周围会看到一条丑陋的黄色粗线。大概表明电影片段是聚焦的,但通常它不在任何地方。这是否意味着该对象不可聚焦,但我还是以某种方式强制关注它?

我意识到上述问题不是很清楚,我不希望实际回答这些问题。但我想表明的是,我似乎做错了什么。所以主要的问题是:是否有一种简单的方法可以在Flash中获得模态行为?我认为从头开始编程并管道和处理各种小事件是我不应该做的事情。

最令我烦恼的事实是我需要这个模态寡妇来处理和显示一些边缘案例错误消息。所以付出这么多努力似乎并不合适。也许,有一种完全不同的方式。

我知道这个问题可能没有得到足够多的研究支持,但我开始研究一些我认为需要半小时才能完成的事情,而且已经有几个小时了。我可能会做更系统的研究,并在以后发布更具体的问题。

2 个答案:

答案 0 :(得分:1)

很简单: 你只需要添加一个覆盖整个闪光灯的矩形,然后在它上面添加模态窗口。此矩形将捕获所有鼠标事件。如果需要,可以将焦点设置为null,确保没有键盘事件。 以下代码是此矩形的类。在模态窗口之前用addChild()添加它。

import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;

public class ModalCoverSprite extends Sprite
{
    public function ModalCoverSprite()
    {
        super();
        graphics.beginFill( 0, 0.3 ); //alpha can be 0 as well.
        graphics.drawRect( 0, 0, 100, 100 );
        graphics.endFill( );
        addEventListener(Event.ADDED_TO_STAGE, onAdded);

    }

    private function fitToBrowser():void 
    {
        width=stage.stageWidth;
        height=stage.stageHeight;
    }

    private function onBrowserResize(event:Event):void
    {
        fitToBrowser();
    }

    private function onAdded(event:Event):void 
    {
        fitToBrowser();
        stage.addEventListener( ExternalBrowserEvent.RESIZE, onBrowserResize );
        addEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
    }

    protected function onRemoved(event:Event):void
    {
        stage.removeEventListener( ExternalBrowserEvent.RESIZE, onBrowserResize );
        removeEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
    }
}

}

答案 1 :(得分:0)

经过一些更多的实验和调查后,我想我找到了一个相当干净的解决方案。其中大部分内容基于FocusEvent event官方文档中的示例。以下是植入的简化版本。

package
{

    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.FocusEvent;
    import flash.display.Sprite;
    import flash.display.Stage;

    public class Message
    {

        private static var overlay : Sprite;
        private static var dialog : Sprite;

        public static function show(stage : Stage, message : String)
        {

            // Close existing (if any).
            close();

            // Create dialog. They overlay sprite overlays the entire scene.
            overlay = createOverlay();
            dialog = createDialog(message);
            overlay.addChild(dialog);
            stage.addChild(overlay);

            // steal focus
            stage.focus = overlay;

            // Make sure the ugly yellow focus rectangle is hidden. Hiding it seems
            // to have one additional benefit. If we don’t do it, one can still 
            // change the focus using left and right arrow keys. The focus rectangle
            // actually moves to another element in the scene (first time I saw
            // something like this in Flash). If we hide it, the left and right arrow
            // keys actually don’t do anything. I did not find any documentation
            // related to this. So it may change in future. But if it changes,
            // possible workaround could be to simply catch the keyboard events
            // and prevent propagation. Such approach is also used in the official
            // AS3 documentation of the FocusEvent class:
            // 
            //   http://livedocs.adobe.com/
            //       flash/9.0/ActionScriptLangRefV3/flash/events/FocusEvent.html
            //
            stage.stageFocusRect = false;

            // Even though the message overlays the entire stage, if you click
            // on it, it loses focus. My guess is that Flash does not find
            // anything obvious which can be focused (such as a textbox). The
            // following below forces Flash to keep the focus on the message.
            // This approach is also used in an example in the AS3 documentation,
            // of the of the FocusEvent class (see the link above) so it gives it
            // some credibility.
            overlay.addEventListener(MouseEvent.CLICK,
                function(event : MouseEvent) : void { stage.focus = overlay; });

            // In addition, when the entire Flash loses focus and it gets it later 
            // back, the container (browser) does not restore the previously focused
            // element. So we have to do it ourselves.
            stage.addEventListener(Event.ACTIVATE,
                function(event : Event) : void { stage.focus = overlay; });

            // And apparently, swallow all keyboard events.
            overlay.addEventListener(KeyboardEvent.KEY_DOWN,
                function(event : KeyboardEvent) : void { event.stopPropagation(); });

        }

        public static function close() : void
        {
            // snip ...
        }

        private static function createOverlay() : Sprite
        {
            // snip ...
        }

        private static function createDialog(message : String) : Sprite
        {
            // snip ...
        }

    }

}