Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Ловля события mouseLeave (http://www.flasher.ru/forum/showthread.php?t=91086)

BlooDHounD 24.01.2007 15:20

Ловля события mouseLeave
 
Вот написал класс, который генерит события у Stage, если мышка его покинула или вернулась.
Может конечно коряво, поэтому прошу внести корективы, если у кого-то есть замечания.
ASdocs недописаны :) так ... набросал ...
Код:

package game.utils {

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

        public final class StageUtils {

                public static function registerEvents(stage:Stage):void {
                        _stage = stage;
                       
                        _stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveEventHandler);
                        _stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
                        // при создании сразу диспатчим событие
                        if ( _stage.mouseX <= 0 || _stage.mouseX >= _stage.stageWidth || _stage.mouseY <= 0 || _stage.mouseY >= _stage.stageHeight ) {
                                dispatchStageMouseOutEvent();
                                // если мы уже находимся за пределами, надо назначить новое событие
                                _stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
                        } else {
                                dispatchStageMouseOverEvent();
                        }
                }

                public static function unRegisterEvents(stage:Stage):void {
                        _stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
                        _stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
                        _stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
                        _stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveEventHandler);
                }

                //--------------------------------------------------------------------------
                //
                //  Class variables
                //
                //--------------------------------------------------------------------------

                /**
                * @private
                * Нужно ли удалить листенер при возвращениии мышки в окно?
                */
                private static var _removeMouseMove:Boolean;

                /**
                * @private
                * Наш стэйдж храним тут.
                */
                private static var _stage:Stage;

                //--------------------------------------------------------------------------
                //
                //  Class properties
                //
                //--------------------------------------------------------------------------

                /**
                * @private
                */
                private static var _stageLeave:Boolean;

                public function get stageLeave():Boolean {
                        return _stageLeave
                }

                //--------------------------------------------------------------------------
                //
                //  Private class methods
                //
                //--------------------------------------------------------------------------

                /**
                * @private
                * Диспатчим событие выхода за пределы.
                */
                private static function dispatchStageMouseOutEvent():void {
                        if (_stageLeave) return;
                        _stageLeave = true;
                        _stage.dispatchEvent(new Event("stageMouseOut"));
//                        trace("mouseOut");
                }

                /**
                * @private
                * Диспатчим событие входа обратно.
                */
                private static function dispatchStageMouseOverEvent():void {
                        if (!_stageLeave) return;
                        _stageLeave = false;
                        _stage.dispatchEvent(new Event("stageMouseOver"));
//                        trace("mouseIn");
                }

                //--------------------------------------------------------------------------
                //
                //  Event handlers
                //
                //--------------------------------------------------------------------------

                /**
                * @private
                * Нажали мышку. Обработчик выбегания за границу срабатывает только по отпусканию мыши,
                * поэтому устанавливаем слежение за движением мыши и удаляем обработчик.
                */
                private static function mouseDownEventHandler(event:MouseEvent):void {
                        event
                        _stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
                        _stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
                }

                /**
                * @private
                * Отпустили мышку. Удалим всякую фигню.
                */
                private static function mouseUpEventHandler(event:MouseEvent):void {
                        _stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
                        _stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
                }

                /**
                * @private
                * Двигаем мышкой.
                * Обрабатываем, когда мышка уже за пределами, или нажата.
                */
                private static function mouseMoveEventHandler(event:MouseEvent):void {
                        var stageLeave:Boolean = ( event.stageX <= 0 || event.stageX >= _stage.stageWidth || event.stageY <= 0 || event.stageY >= _stage.stageHeight );
       
                        if (!_stageLeave && stageLeave) {
                                dispatchStageMouseOutEvent();
                        } else if (_stageLeave && !stageLeave) {
                                if (_removeMouseMove) {
                                        _stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
                                        _removeMouseMove = false;
                                }
                                dispatchStageMouseOverEvent();
                        }
                }

                /**
                * @private
                * Мышка вышла за пределы.
                */
                private static function mouseLeaveEventHandler(event:Event):void {
                        dispatchStageMouseOutEvent();
                        // вышли за грницы. надо как-то отследить что мы вернулись
                        _stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
                }

        }
}

Пример:
Код:

StageUtils.registerEvents(this.stage);
this.stage.addEventListener("stageMouseOver", this.stageMouseOverHandler);
this.stage.addEventListener("stageMouseOver", this.stageMouseOutHandler);


MerlinTwi 25.01.2007 13:03

Раз уж, просил замечания ;)
Цитата:

Код:

private static function mouseDownEventHandler(event:MouseEvent):void {
        event <-- это что???
        _stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
        _stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
}


Пример не работает, т.к. обе функции подписаны на одно событие "stageMouseOver" (на твоей могиле будет написано "умер от copy-paste")

Названия событий стоило бы объявить константами в классе.

Не генерится событие в случае переключения по Alt-tab, хотя это можно отловить по Event.DEACTIVATE, рекомендую добавить.

BlooDHounD 25.01.2007 13:15

Цитата:

event <-- это что???
это я собирался сперва Stage вытаскивать из eventa. потом забыл удалить :)
Код:

var stage:Stage = event.target as Stage;
Цитата:

Пример не работает, т.к. обе функции подписаны на одно событие "stageMouseOver" (на твоей могиле будет написано "умер от copy-paste")
От того количества, которое ты повторял мне эту фразу, я решил увековечить и поставить табличку на стол :)
Цитата:

Названия событий стоило бы объявить константами в классе.
Они объявлены. просто класс события лень впихивать в пост вот и вписал просто как строки
Цитата:

Не генерится событие в случае переключения по Alt-tab, хотя это можно отловить по Event.DEACTIVATE, рекомендую добавить.
сенкс.


Часовой пояс GMT +4, время: 22:47.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.