|
|
|||||
Регистрация: May 2011
Сообщений: 221
|
управление потоком событий
Итак, общая задача состоит в том, чтобы создавать окно, которое удаляется по клику вне его области, при том, что оно создается кликом по другой кнопке.
Базовая схема реализации: кнопка, по событию MOUSE_DOWN, делегирует объекту сцены создание объекта окна -> сцена создает окно -> окно дажидается события ADDED_TO_STAGE и в нем добавляет себе слушателя stage.addEventListener(MouseEvent.MOUSE_DOWN, onClickOutside); и при возникновении этого события удаляет себя со сцены. в чем вобщем-то проблема:окно удаляется сразу же после создания, потому что получает то же самое событие, которое необходимо для его создания. Попытки предпринятые для решения: -использвать в слушателе окна параметр useCapture, который, насколько я понимаю адресует событие объекту сразу же, как только событие было получено. Не помогло. По какой-то причине окно удаляется даже если клик происходит по нему -обрабатывать только в фазе e.eventPhase == EventPhase.AT_TARGET. Не помогло. Событие обрабатывается только если клик происходит исключительно по стейджу, если таргетится любой другой объект сцены - событие не срабатывает. Как можно решить? |
|
|||||
Регистрация: Aug 2012
Сообщений: 70
|
А почему MOUSE_DOWN, а не MOUSE_CLICK?
|
|
|||||
Не правильный это вообще подход, сцене посылать события на создание окна.
Менеджер окон логичнее сделать в отдельном классе со статическим методом. Проще говоря вызвал в любом месте WindowManager.addWindow(); Окно появилось. В нем при добавлении на сцену к сцене привешался слушатель MouseEvent.CLICK, и если щелчок произошел не по окну, оно само удаляется. Не нужно ничего мудрить. |
|
|||||
Регистрация: May 2011
Сообщений: 221
|
Пожалуйста, часть проблемного класса BaseWindow
public function BaseWindow(gameScene:Main) { this.gameScene = gameScene; addEventListener(Event.ADDED_TO_STAGE, added); } private function added(e:Event):void { removeEventListener(Event.ADDED_TO_STAGE, added); stage.addEventListener(MouseEvent.MOUSE_DOWN, onClickOutside); } private function onClickOutside(e:MouseEvent):void { removeWindow(); } protected function removeWindow():void { gameScene.removeWindow(); } |
|
|||||
блогер
Регистрация: Jun 2005
Адрес: Господи пожалуйста не Новосибирск
Сообщений: 6,598
Записей в блоге: 17
|
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
Цитата:
Вот упрощенный пример: package { import flash.display.Sprite; import flash.display.Stage; import flash.events.MouseEvent; public class PopupWindow extends Sprite { private static var _stage: Stage; private static var _window: PopupWindow = null; public function PopupWindow() { graphics.beginFill(0xFFFF00); graphics.drawRect(0, 0, 250, 100); graphics.endFill(); } public function dispose():void { graphics.clear(); if (parent) parent.removeChild(this); } public static function show():void { if (!_stage) throw "сначала нужно инициализировать"; if (_window) return; _window = new PopupWindow(); _window.x = (_stage.stageWidth - _window.width) / 2; _window.y = (_stage.stageHeight - _window.height) / 2; _stage.addChild(_window); } public static function initizlize(stage:Stage):void { if (_stage) return; _stage = stage; _stage.addEventListener(MouseEvent.CLICK, onClick); } static private function onClick(e:MouseEvent):void { if (_window) { if (e.target != _window) { _window.dispose(); _window = null; } } } } } |
|
|||||
Регистрация: May 2011
Сообщений: 221
|
Psycho Tiger, Да, это было бы неплохо разместить в кнопке, которая создает окно, проблема только одна, что кнопка принимает событие раньше, чем окно, а потому, если создать целчком по кнопке окно и затем еще раз кликнуть по кнопке, то создатся еще одно окно, вместо того, чтобы удалить текущее.
caseyryan, к сожалению сейчас нет возможности оттестировать, но вероятнее всего, что если окно будет показано по клику вне области окна (то есть по клику на кнопку), то оно будет так же уничтожено сразу же после создания, потому что MouseEvent.CLICK придет туда во время баблинга. И при такой реализации еще встает вопрос о том, как взаимодействовать с содержимым окна, если оно есть, потому что e.target внутри окна, точно уже не будет _window. Последний раз редактировалось Фенёк; 18.02.2013 в 13:51. |
|
|||||
Цитата:
__________________
http://www.chessmax.ru |
|
|||||
Регистрация: May 2011
Сообщений: 221
|
Inet_PC, дальнейшем это приведет к разрастанию условий. То есть у меня например есть два состояния в приложении: обычный режим и режем строительства. Если кликаем по кнопке — запускается режим стрительства, если мимо игрового поля — обычный режим. Это получается для каждого объекта придется писать условие о том открыто ли окно или какой режим активен.
|
Часовой пояс GMT +4, время: 05:13. |
|
« Предыдущая тема | Следующая тема » |
|
|