![]() |
|
||||||||||
|
|||||
|
Регистрация: Apr 2010
Сообщений: 170
|
Всем доброго вечера!
У меня есть базовый класс RenderWindow от которого наследуется любое GUI. Собственно поведение RenderWindow устроено так, что он обрабатывает события мыши и посылает события с типом произошедшего события мыши. Собственно вот как это устроено: package d.app.render { import d.app.event.AppEvent; import d.app.event.appEvent.WindowAppEvent; import flash.display.DisplayObject; import flash.events.MouseEvent; public class RenderWindow extends RenderObject { public static const RW_TYPE_ROOT :uint = 0; public static const RW_TYPE_MAIN_MENU :uint = 1; public static const RW_TYPE_MAIN_MENU_BUTTON :uint = 2; public static const RW_TYPE_CONTEXT_MENU :uint = 3; public static const RW_TYPE_CONTEXT_MENU_ITEM :uint = 4; public static const RW_TYPE_TEXT_BUTTON :uint = 5; protected var rwType:uint=RW_TYPE_ROOT; protected var rwIsListener:Boolean=false; protected var rwIsDown:Boolean=false; public function RenderWindow(_type:uint,_name:String,_parent:RenderObject,_display:DisplayObject) { super(RO_TYPE_WINDOW,_name,_parent,_display); rwType=_type; mouseEnabled=true; } public final function rwGetType():uint { return rwType; } public function rwBegin():void { } public function rwUpdate():void { } public function rwResize():void { } public function rwEnd():void { } public override function roEnable():Boolean { if(roIsEnable) return false; roIsEnable=true; if(!rwIsListener) { addEventListener(MouseEvent.MOUSE_OUT,rwOnMouseOut); addEventListener(MouseEvent.MOUSE_OVER,rwOnMouseOver); addEventListener(MouseEvent.MOUSE_MOVE,rwOnMouseMove); addEventListener(MouseEvent.MOUSE_DOWN,rwOnMouseDown); addEventListener(MouseEvent.MOUSE_UP,rwOnMouseUp); } rwOnEnable(); return true; } public override function roDisable():Boolean { if(!roIsEnable) return false; if(rwIsListener) { removeEventListener(MouseEvent.MOUSE_OUT,rwOnMouseOut); removeEventListener(MouseEvent.MOUSE_OVER,rwOnMouseOver); removeEventListener(MouseEvent.MOUSE_MOVE,rwOnMouseMove); removeEventListener(MouseEvent.MOUSE_DOWN,rwOnMouseDown); removeEventListener(MouseEvent.MOUSE_UP,rwOnMouseUp); } roIsEnable=false; rwOnDisable(); return true; } protected function rwOnEnable():void { } protected function rwOnDisable():void { } public override function roLock():Boolean { if(roIsLock) return false; roIsLock=true; if(!rwIsListener) { addEventListener(MouseEvent.MOUSE_OUT,rwOnMouseOut); addEventListener(MouseEvent.MOUSE_OVER,rwOnMouseOver); addEventListener(MouseEvent.MOUSE_MOVE,rwOnMouseMove); addEventListener(MouseEvent.MOUSE_DOWN,rwOnMouseDown); addEventListener(MouseEvent.MOUSE_UP,rwOnMouseUp); } rwOnLock(); return true; } public override function roUnlock():Boolean { if(!roIsLock) return false; if(rwIsListener) { removeEventListener(MouseEvent.MOUSE_OUT,rwOnMouseOut); removeEventListener(MouseEvent.MOUSE_OVER,rwOnMouseOver); removeEventListener(MouseEvent.MOUSE_MOVE,rwOnMouseMove); removeEventListener(MouseEvent.MOUSE_DOWN,rwOnMouseDown); removeEventListener(MouseEvent.MOUSE_UP,rwOnMouseUp); } roIsLock=false; rwOnUnlock(); return true; } protected function rwOnLock():void { } protected function rwOnUnlock():void { } protected function rwOnMouseOut(_event:MouseEvent):void { rwIsDown=false; dispatchEvent(new WindowAppEvent(AppEvent.WINDOW_OUT,this)); rwOnAdditionMouseOut(_event); } protected function rwOnMouseOver(_event:MouseEvent):void { rwIsDown=false; dispatchEvent(new WindowAppEvent(AppEvent.WINDOW_OVER,this)); rwOnAdditionMouseOver(_event); } protected function rwOnMouseMove(_event:MouseEvent):void { dispatchEvent(new WindowAppEvent(AppEvent.WINDOW_MOVE,this)); rwOnAdditionMouseMove(_event); } protected function rwOnMouseDown(_event:MouseEvent):void { rwIsDown=true; dispatchEvent(new WindowAppEvent(AppEvent.WINDOW_DOWN,this)); rwOnAdditionMouseDown(_event); } protected function rwOnMouseUp(_event:MouseEvent):void { if(rwIsDown) dispatchEvent(new WindowAppEvent(AppEvent.WINDOW_CLICK,this)); rwIsDown=false; rwOnAdditionMouseUp(_event); } protected function rwOnAdditionMouseOut(_event:MouseEvent):void { } protected function rwOnAdditionMouseOver(_event:MouseEvent):void { } protected function rwOnAdditionMouseMove(_event:MouseEvent):void { } protected function rwOnAdditionMouseDown(_event:MouseEvent):void { } protected function rwOnAdditionMouseUp(_event:MouseEvent):void { } } } И вот я от RenderWindow наследую два класса: 1. GUIMainMenu 2. GUIMenuButton GUIMenuButton я прикрепляю к GUIMainMenu в контейнер его. И вот в чём ошибка: когда я тыкаю мышкой на GUIMenuButton, у меня вызывается два события: 1. Событие GUIMenuButton 2. Событие GUIMainMenu Почему так? Ведь GUIMenuButton лежит в GUIMainMenu и перекрывает его. Тогда почему два события происходят? |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Обычное всплытие События. Вы считаете, что можете кликнуть по содержимому контейнера, не кликнув при этом по самому контейнеру?
__________________
Reality.getBounds(this); |
|
|||||
|
Потому, видимо, что меню также рассылает событие получателем которого является кнопка, в фазе "захвата". Различить их можно по свойствам currentTarget, и eventPhase.
А в чем удобство вашего такого подхода? Зачем так вообще сделано? |
|
|||||
|
Регистрация: Apr 2010
Сообщений: 170
|
Wolsh
Цитата:
fish_r Цитата:
Цитата:
Собственно сейчас я пытаюсь сделать главное меню. Нажимаю на кнопку и появляется контекстное меню. А когда я тыкаю в любое другое RenderWindow (то есть имя полученного в событие RenderWindow не совпадёт с именем RenderWindow меню), то я закрываю текущее контекстное меню. То есть есть меню GUIMainMenu, которое полоской простирается во всю ширину экрана. На этой полоске в самом начале (0,0) располагается кнопка меню GUIMenuButton. Как я нажимаю на кнопку, я открываю прикрёплённое за кнопкой GUIContextMenu, а как у меня происходит нажатие на любой другой RenderWindow, то я скрываю контекстное меню (правда оно не скрывается если тыкнули на кнопку, которая наоборот открывает это контекстное меню). Так вот, по сути если открыто контекстное меню и мы тыкнули на главное меню в его любой части, но там где нет кнопки открытия этого контекстного меню, мы должны закрыть меню. Так и происходит. Но когда я тыкаю на кнопку открытия этого меню, у меня приходят два события: 1. Событие GUIMenuButton - контекстное меню открывается 2. Событие GUIMainMenu - контекстное меню закрывается В результате я никогда не увижу это контекстное меню. Вот зачем оно два события посылает и как это исправить? |
|
|||||
|
Вот в том то и дело, что Меню рассылает событие получателем которого является Кнопка, в первой фазе event flow. А ваша конструкция не имеет инструментов различения фазы и принадлежности события, поэтому и "захватывает" всё подряд. Почитайте документацию о реализации событий в среде флеш.
По поводу вашего минифреймворка. Может я не правильно, или не до конца понял вашу мысль, но кажется, всё, каким-то... сложным. Я бы например делал бы так: |
|
|||||
|
Регистрация: Apr 2010
Сообщений: 170
|
fish_r
Цитата:
|
|
|||||
|
Вы не правильно понимаете модель распространения событий ( отображаемых объектов), поэтому и говорю, что вам нужно бы ознакомиться с ней, тогда всё станет яснее...
Меню не рассылает кнопке. Меню просто диспатчит событие двигающееся от стейджа к Кнопке. Ваша конструкция обрабатывает это событие так, как будет его получателем является Меню, а на деле это не так. Отсюда и путаница. В общем случае обрабатывается это так: private function onClick( evt:MouseEvent ):void { // проверяем - принадлежит ли полученное событие собственно Меню if( evt.target !== Menu ) return; // другой вариант, по фазе события: принадлежит ли событие объекту получателю if( evt.eventPhase !== EventPhase.AT_TARGET ) return; } То есть я вас сейчас ещё больше запутаю ![]() Второй вариант точнее сформулировать так: получено ли событие в фазе обработки получателем (если это одна из других двух фаз, захвата или всплытия - выходим без обработки). Последний раз редактировалось fish_r; 18.04.2012 в 01:28. |
|
|||||
|
Регистрация: Apr 2010
Сообщений: 170
|
fish_r
Можете дать ссылку на статью, где понятным языком рассказано про события? Просто то что Вы написали, я не совсем понял. |
|
|||||
|
Я, вообще, об этом ещё у Мука читал. Там довольно ясно описано. Ну вот есть в документации: http://help.adobe.com/ru_RU/as3/dev/...0204-7dfb.html. Ещё по форуму посмотрите, этот вопрос, конечно не однократно поднимался здесь.
|
|
|||||
|
Регистрация: Apr 2010
Сообщений: 170
|
fish_r
Спасибо, завтра почитаю. Если будут вопросы, я сюда напишу. |
![]() |
![]() |
Часовой пояс GMT +4, время: 05:32. |
|
|
« Предыдущая тема | Следующая тема » |
|
|