Модальное окно во Flash - PullRequest
1 голос
/ 09 июля 2009

Короткая версия:

Легко / выполнимо / возможно ли программировать модальное окно во Flash (AS3)? Есть ли для него встроенная функциональность?

Длинная версия:

Я работаю над виджетом Flash (в AS3) и хотел бы иметь возможность показывать видеоклип в модальном режиме. По сути, мне нужно простое модальное окно внутри виджета. До сих пор я узнал, что мне нужно самому реализовать «модальность» (в AS3). Раньше что-то было в предыдущих версиях Flash, и что-то есть во Flex, но у меня нет опыта работы с Flax, и я не уверен, с чем это связано.

Я сам написал это без какого-либо глубокого планирования и вскоре столкнулся с некоторыми проблемами. Кажется, что корень проблемы в том, что я не могу сосредоточиться на мувиклипе (или, если быть точным, InteractiveObject). Я обрабатываю события KEY_FOCUS_CHANGE и MOUSE_FOCUS_CHANGE, пытаясь предотвратить потерю фокуса FocusEvent.preventDefault(). Но мне все же удается потерять фокус нажатием мыши. Что еще более странно, так это то, что когда я навязываю фокус с помощью свойства Stage.focus, я получаю уродливую толстую желтую линию вокруг моего клипа. Предположительно указывает на то, что видеоклипы сфокусированы, но обычно его нет нигде. Значит ли это, что объект не фокусируется, но я все равно каким-то образом заставляю его фокусироваться?

Я понимаю, что приведенные выше вопросы не очень ясны, и я не ожидаю, что на самом деле на них отвечу. Но я пытаюсь указать, что мне кажется, что я делаю что-то не так. Итак, главный вопрос заключается в следующем: есть ли простой способ получить модальное поведение во Flash? Я думаю, что программировать это с нуля, обвязывать и обрабатывать различные мелкие события - это то, чего я не должен делать.

Больше всего меня раздражает то, что мне нужна эта модальная вдова для обработки и отображения некоторых сообщений об ошибках в крайнем случае. И поэтому вкладывать столько усилий в это не кажется правильным. Может быть, есть совершенно другой способ.

Мне известно о том, что этот вопрос, возможно, не подтверждается достаточным количеством исследований, но я начал работать над чем-то, что, как я думал, займет у меня полчаса, а это уже несколько часов. Я могу провести более систематическое исследование и позже опубликовать более конкретные вопросы.

Ответы [ 2 ]

1 голос
/ 06 ноября 2012

Все просто: Вы просто добавите прямоугольник, который будет покрывать всю вспышку, и добавите модальное окно поверх него. все события мыши будут пойманы этим прямоугольником. Если вы хотите, вы можете установить фокус на ноль, не допуская событий клавиатуры. следующий код является классом для этого прямоугольника. добавьте его с помощью 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);
    }
}

}

0 голосов
/ 10 июля 2009

После еще нескольких экспериментов и исследований, я думаю, я нашел прилично чистое решение. Большая часть этого основана на примере официальной документации события FocusEvent . Далее следует упрощенная версия имплантации.

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 ...
        }

    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...