Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 18.02.2013, 11:42
Фенёк вне форума Посмотреть профиль Отправить личное сообщение для Фенёк Найти все сообщения от Фенёк
  № 1  
Ответить с цитированием
Фенёк

Регистрация: May 2011
Сообщений: 221
Question управление потоком событий

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

Базовая схема реализации: кнопка, по событию MOUSE_DOWN, делегирует объекту сцены создание объекта окна -> сцена создает окно -> окно дажидается события ADDED_TO_STAGE и в нем добавляет себе слушателя stage.addEventListener(MouseEvent.MOUSE_DOWN, onClickOutside); и при возникновении этого события удаляет себя со сцены.

в чем вобщем-то проблема:окно удаляется сразу же после создания, потому что получает то же самое событие, которое необходимо для его создания.

Попытки предпринятые для решения:

-использвать в слушателе окна параметр useCapture, который, насколько я понимаю адресует событие объекту сразу же, как только событие было получено. Не помогло. По какой-то причине окно удаляется даже если клик происходит по нему

-обрабатывать только в фазе e.eventPhase == EventPhase.AT_TARGET. Не помогло. Событие обрабатывается только если клик происходит исключительно по стейджу, если таргетится любой другой объект сцены - событие не срабатывает.

Как можно решить?

Старый 18.02.2013, 12:05
Hauts вне форума Посмотреть профиль Отправить личное сообщение для Hauts Посетить домашнюю страницу Hauts Найти все сообщения от Hauts
  № 2  
Ответить с цитированием
Hauts
 
Аватар для Hauts

блогер
Регистрация: Feb 2008
Адрес: Россия, Новосибирск, Академгородок
Сообщений: 2,112
Записей в блоге: 1
Отправить сообщение для Hauts с помощью ICQ Отправить сообщение для Hauts с помощью Skype™
"дажидается"

Дайте код посмотреть.
__________________
hauts.ru

Старый 18.02.2013, 12:10
NoisyFlasher вне форума Посмотреть профиль Отправить личное сообщение для NoisyFlasher Найти все сообщения от NoisyFlasher
  № 3  
Ответить с цитированием
NoisyFlasher
 
Аватар для NoisyFlasher

Регистрация: Aug 2012
Сообщений: 70
А почему MOUSE_DOWN, а не MOUSE_CLICK?

Старый 18.02.2013, 12:13
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 4  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Не правильный это вообще подход, сцене посылать события на создание окна.
Менеджер окон логичнее сделать в отдельном классе со статическим методом.
Проще говоря вызвал в любом месте WindowManager.addWindow(); Окно появилось. В нем при добавлении на сцену к сцене привешался слушатель MouseEvent.CLICK, и если щелчок произошел не по окну, оно само удаляется. Не нужно ничего мудрить.

Старый 18.02.2013, 13:09
Фенёк вне форума Посмотреть профиль Отправить личное сообщение для Фенёк Найти все сообщения от Фенёк
  № 5  
Ответить с цитированием
Фенёк

Регистрация: May 2011
Сообщений: 221
Пожалуйста, часть проблемного класса BaseWindow
Код AS3:
		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();
		}
caseyryan, нет разницы чисто технически как реализовывать. То есть кончено архитектурно это будет более аккуратное решение, но сейчас не в этом проблема. Даже если и так делать, то объект окна так же будет удаляться при его создание, поскольку в фазе бабблинга будет получать событие.

Старый 18.02.2013, 13:12
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 6  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Господи пожалуйста не Новосибирск
Сообщений: 6,598
Записей в блоге: 17
Код AS3:
event.stopImmediatePropogation()

Старый 18.02.2013, 13:26
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 7  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
caseyryan, нет разницы чисто технически как реализовывать.
Разница огромна. У меня все всплывающие окна реализуются через статические менеджеры, и все равботает.

Вот упрощенный пример:

Код AS3:
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;
				}
			}
		}
	}
 
}
Сначала где-то в документ классе инициализируем, а потом просто в любом месте программы вызываем методо PopupWindow.show()

Старый 18.02.2013, 13:28
Фенёк вне форума Посмотреть профиль Отправить личное сообщение для Фенёк Найти все сообщения от Фенёк
  № 8  
Ответить с цитированием
Фенёк

Регистрация: May 2011
Сообщений: 221
Psycho Tiger, Да, это было бы неплохо разместить в кнопке, которая создает окно, проблема только одна, что кнопка принимает событие раньше, чем окно, а потому, если создать целчком по кнопке окно и затем еще раз кликнуть по кнопке, то создатся еще одно окно, вместо того, чтобы удалить текущее.

caseyryan, к сожалению сейчас нет возможности оттестировать, но вероятнее всего, что если окно будет показано по клику вне области окна (то есть по клику на кнопку), то оно будет так же уничтожено сразу же после создания, потому что MouseEvent.CLICK придет туда во время баблинга. И при такой реализации еще встает вопрос о том, как взаимодействовать с содержимым окна, если оно есть, потому что e.target внутри окна, точно уже не будет _window.


Последний раз редактировалось Фенёк; 18.02.2013 в 13:51.
Старый 18.02.2013, 14:25
Inet_PC вне форума Посмотреть профиль Отправить личное сообщение для Inet_PC Посетить домашнюю страницу Inet_PC Найти все сообщения от Inet_PC
  № 9  
Ответить с цитированием
Inet_PC
 
Аватар для Inet_PC

Регистрация: Feb 2009
Адрес: Гы...поди, найди!
Сообщений: 853
Записей в блоге: 1
Цитата:
Psycho Tiger, Да, это было бы неплохо разместить в кнопке, которая создает окно, проблема только одна, что кнопка принимает событие раньше, чем окно, а потому, если создать целчком по кнопке окно и затем еще раз кликнуть по кнопке, то создатся еще одно окно, вместо того, чтобы удалить текущее.
Ну так кто Вам мешает проверить открыть окно или нет? И если открыто, то либо ничего не делайте, либо закрывайте окно.
__________________
http://www.chessmax.ru

Старый 18.02.2013, 14:31
Фенёк вне форума Посмотреть профиль Отправить личное сообщение для Фенёк Найти все сообщения от Фенёк
  № 10  
Ответить с цитированием
Фенёк

Регистрация: May 2011
Сообщений: 221
Inet_PC, дальнейшем это приведет к разрастанию условий. То есть у меня например есть два состояния в приложении: обычный режим и режем строительства. Если кликаем по кнопке — запускается режим стрительства, если мимо игрового поля — обычный режим. Это получается для каждого объекта придется писать условие о том открыто ли окно или какой режим активен.

Создать новую тему Ответ Часовой пояс GMT +4, время: 05:13.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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