![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Nov 2009
Сообщений: 5
|
Доброго времени суток.
Написал простенький класс для вывода мсдж-бокса на экран. public class MsgBox extends Sprite { private const MAX_MSGS_IN_QUEUE:uint = 10; public static const TYPE_OK = 1; public static const TYPE_YESNO = 2; public static const OK = 1; public static const YES = 2; public static const NO = 3; private var m_arrMsgs:Vector.<msg_info>; private var m_arrBtns:Array; private var m_sprBtns:Sprite; public function MsgBox() { m_arrMsgs = new Vector.<msg_info>(); m_sprBtns = new Sprite(); addChild( m_sprBtns ); m_sprBtns.addEventListener( MouseEvent.CLICK, OnBtnClick ); m_arrBtns = new Array(); visible = false; } // Конструктор public function Create( msg:msg_info ):Boolean { if( m_arrMsgs.length >= MAX_MSGS_IN_QUEUE ) return false; m_arrMsgs.push( msg ); if( !visible ) Show(); return true; } // Create private function Show():void { TfTitle.text = m_arrMsgs[0].title; TfText.text = m_arrMsgs[0].text; switch( m_arrMsgs[0].type ) { case TYPE_OK: { m_arrBtns[OK] = CreateButton( "Ok", xx, yy ); } break; case TYPE_YESNO: { m_arrBtns[YES] = CreateButton( "Да", xx, yy ); m_arrBtns[ NO] = CreateButton( "Нет", xx, yy ); } break; } // switch if( !visible ) { dispatchEvent( new MsgBoxEvent( MsgBoxEvent.SHOW ) ); visible = true; } } // Show public function Hide():Boolean { RemoveAllButtons(); m_arrMsgs.shift(); if( m_arrMsgs.length == 0 ) { dispatchEvent( new MsgBoxEvent( MsgBoxEvent.HIDE ) ); visible = false; return true; } else { Show(); return false; } } // Hide public function OnBtnClick( e:MouseEvent ) { Hide(); } // OnBtnClick private function CreateButton( sCaption:String, x_pos:Number, y_pos:Number ):Button { var btn:Button = new Button(); btn.x = x_pos; btn.y = y_pos; btn.label = sCaption; m_sprBtns.addChild( btn ); return btn; } // CreateButton private function RemoveAllButtons() { for( var key in m_arrBtns ) { m_sprBtns.removeChild( m_arrBtns[key] ); m_arrBtns[key] = null; } m_arrBtns = null; m_arrBtns = new Array(); } // RemoveAllButtons public function GetButton ( id:uint ) { return m_arrBtns[id]; } public function GetButtons() { return m_arrBtns; } m_MsgBox = new MsgBox(); addChild( m_MsgBox ); // Создаем мсдж-бокс var Msg:msg_info = new msg_info(); Msg.type = MsgBox.TYPE_YESNO; Msg.title = 'Вы действительно хотите выйти?'; Msg.text = 'Выход'; m_MsgBox.Create( Msg ); // WeakReference слушатели не помешают кнопке удалиться m_MsgBox.GetButton( MsgBox.YES ).addEventListener( MouseEvent.CLICK, OnExit , false, 0, true ); m_MsgBox.GetButton( MsgBox.NO ).addEventListener( MouseEvent.CLICK, Continue, false, 0, true ); И вроде бы всё нормально, но слушателей никто не удаляет. Они так и остаются висеть и ловить сообщения несуществующей кнопки, после того, как мсдж-бокс закрыли. К тому же, приходится использовать WeakReference, чтобы кнопки могли удалиться из памяти. Прошу совета, как это дело лучше перепроектировать. Переопределить addEventListener для Button? Или вообще запретить получение указателей на кнопки MsgBox-а( тогда при создании мсдж-бокса, нужно будет передать указатель на метод, который дернется при mouseEvent.CLICK )? Или дописывать каждый раз удаление слушателя в вызываемый им же метод? А может есть какой-то секрет удаления слушателей при удалении объекта? Буду рад услышать любые мнения. |
|
|||||
|
REMOVED_FROM_STAGE, думаю.
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Регистрация: Nov 2009
Сообщений: 5
|
Деструктор кнопки? А откуда кнопка узнает, какие на ней слушатели висят?
|
|
|||||
|
зачем вам давать доступ кому попало к своим кнопкам. никакого GetButton быть не должно.
надо отсылать события самим классом MsgBox. например, OK_CLICKED, CANCEL_CLICKED. и подписываться к MsgBox, а не к его кнопкам
__________________
я могу стать всем, если только захочу |
|
|||||
|
Регистрация: Nov 2009
Сообщений: 5
|
А ничего, что придется переписать все нужные события( PRESS, CLICK, ... ) для всех возможных кнопок? Может быть сделать одно событие MsgBox-а BTN_PRESS, BTN_CLICK,... с полем BtnID, а не для каждой кнопки? Или это те же яйца?
|
|
|||||
|
Цитата:
Цитата:
__________________
я могу стать всем, если только захочу |
|
|||||
|
Регистрация: Apr 2009
Сообщений: 117
|
Bomberovich, а что мешает MsgBox генерировать событие DESTROY или CLOSE и вам подписываться на это событие, где уже ручками можно было бы снять все листенеры?
Ну или хотя бы коллбак организовать, типа onClose |
|
|||||
|
Регистрация: Nov 2009
Сообщений: 5
|
Felicast
GentleFLASH Хотелось бы избежать удаления слушателей кнопок(или самого MsgBox-a) внешним классом. Удаляется кнопка - должны удалится все ее слушатели. Пока в голову приходит только: class MsgBox { // Только с помощью этого метода можно будет повесить любого слушателя на любую кнопку public function addEventListenerToButton( uiBtnID:uint, type:String, listener:Function ) { m_listeners.push( { uiBtnID:uiBtnID, type:type, listener:listener } ); m_arrBtns[uiBtnID].addEventListener( type, listener, false, 0, true ); } // addEventListenerToButton // Вызывается при удалении кнопок private function RemoveAllButtonListeners() { for( var i:uint=0; i<m_listeners.length; i++ ) m_arrBtns[m_listeners[i].uiBtnID].removeEventListener( m_listeners[i].type, m_listeners[i].listener, false, 0, true ); m_listeners = new Array(); } // RemoveAllButtonListeners } |
|
|||||
|
Et cetera
Регистрация: Sep 2002
Сообщений: 30,787
|
Можно переопределить addEventListener у самого MsgBox. И вообще, подписываться только у него на кастомные события типа RESULT_YES, RESULT_NO и т. п.. Когда происходит REMOVED_FROM_STAGE, удалять подписчиков.
|
![]() |
![]() |
Часовой пояс GMT +4, время: 15:41. |
|
|
« Предыдущая тема | Следующая тема » |
|
|