Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Сделать собственную кнопку (http://www.flasher.ru/forum/showthread.php?t=171265)

expl 13.11.2011 22:09

Код AS3:

stage.addEventListener(MouseEvent.MOUSE_UP, onMouseEvent);

Без отписки это "ой-ой", будет грузить проц все сильнее и сильнее по мере добавления кнопок, куда бы вы старые не девали, плюс старые будут висеть в памяти.

Плюс, зачем это слушать всем кнопкам, когда отжали только одну?

Как-бы в PushButton из minimalcomps, кнопках из AsWing и Flex вся эта подписка-отписка стейджа одинаково и по-человечески решается.
Я просто думал, вдруг кто знает способ без stage и без SimpleButton
(у нас сейчас используется упрощенное поведение кнопки - вроде глаз не сильно режет - были проблемы во вконтактовском враппере, теперь, может быть, проблема не актуальна, в одном проекте даже кнопки на базе SimpleButton использовали, но по другой причине)

Vektor 13.11.2011 22:54

Правильно говоришь, вот пришлось дописать.
Код AS3:

private var _iCounter:int=0;
//Когда нада удалить кнопки.
onButtonDelete(_mcButton);
onButtonDelete(_mcButton1);
private function onButtonDelete(But:MovieClip):void {
        _iCounter--;
        But.removeEventListener(MouseEvent.MOUSE_OVER, onMouseEvent);
        But.removeEventListener(MouseEvent.MOUSE_OUT, onMouseEvent);
        But.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseEvent);
        if (_iCounter==0) {
                stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseEvent);
        }
        removeChild(But);
        But=null;
}
private function onMouseEvent(event:MouseEvent):void {
        _iCounter++;
}

Цитата:

Плюс, зачем это слушать всем кнопкам, когда отжали только одну?
Кнопки не слушают кто что там отжал, stage слушает и вызыват
Код AS3:

case MouseEvent.MOUSE_UP :
        if (!(event.target is Stage)) {
                event.target.gotoAndStop(2);
        }
        _bDown=false;
        break;

Я сомневаюсь что для (stage.addEventListener(MouseEvent.MOUSE_UP, onMouseEvent);) создаётся несколько слушателей, скорей всего только один.

alatar 13.11.2011 23:01

Цитата:

ну кого реально волнует поведение кнопки в ситуациях типа "нажал, отвёл, навёл, отпустил"?
Дьявол в мелочах.

expl 13.11.2011 23:39

Цитата:

Сообщение от Vektor (Сообщение 1045835)
Правильно говоришь, вот пришлось дописать.
Код AS3:

private var _iCounter:int=0;
//Когда нада удалить кнопки.
onButtonDelete(_mcButton);
onButtonDelete(_mcButton1);
private function onButtonDelete(But:MovieClip):void {
...
_iCounter++;
...


Какой-то ужос на ровном месте, ИМХО вместо
Код AS3:

onButtonCreate(_mcButton,100,100);
onButtonCreate(_mcButton1, 100,200);

создали бы класс-обвертку для одной-единственной кнопки, а потом
Код AS3:

var button:DisplayObject;
button = new MyButton(_mcButton);
button.x = 100;
button.y = 100;
addChild(button);
button = new MyButton(_mcButton1);
button.x = 100;
button.y = 200;
addChild(button);

А то тут куча разделяемых переменных на 2 кнопки, уже счетчики пошли...

Ну и сам этот несчастный класс:
Код AS3:

package {
        import flash.display.Sprite;
        import flash.display.MovieClip;
        import flash.events.MouseEvent;
        public class MyButton extends Sprite
        {
                private var button:MovieClip;
                public function MyButton(button:MovieClip) {
                        this.button = button;
                        this.button.gotoAndStop(1);
                        addEventListener(MouseEvent.ROLL_OVER, onRollOver);
                        addEventListener(MouseEvent.ROLL_OUT, onRollOut);
                        addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
                }
                private var _isOver:Boolean = false;
                private var _isDown:Boolean = false;
                private function onRollOver(event:MouseEvent):void {
                        _isOver = true;
                        updateFrame();
                }
                private function onRollOut(event:MouseEvent):void {
                        _isOver = false;
                        updateFrame();
                }
                private function onMouseDown(event:MouseEvent):void {
                        _isDown = true;
                        updateFrame();
                        // Стейдж здесь уже будет, иначе как на кнопку смогли нажать?
                        stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
                }
                private function onMouseUp(event:MouseEvent):void {
                        // Сработает, даже если отжали за пределами флешки, т.е. отпишемся стопроцентно
                        stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
                        _isDown = false;
                        updateFrame();
                }
                private function updateFrame():void
                {
                        if (_isDown) {
                                if (_isOver) {
                                        this.button.gotoAndStop(4);
                                } else {
                                        this.button.gotoAndStop(3);
                                }
                        } else {
                                if (_isOver) {
                                        this.button.gotoAndStop(2);
                                } else {
                                        this.button.gotoAndStop(1);
                                }
                        }
                }
        }
}


-De- 13.11.2011 23:46

Самый быстрый и безбажный код - тот, которого нет. Не прорабатывая и упрощая не важные вещи можно сильно ускорить разработку. Да, это весьма спорно именно про этот момент, ведь раз сделал и оно везде и всегда.

Vektor, если onMouseEvent не статик, то будет добавлено столько слушателей MOUSE_UP, сколько кнопок. Но убьется вашим кодом только последний.
Мне нравится решение как в коде от expl - слушатель на ап добавляется только при нажатии. Таким образом он максимум один (если извратов не считать) будет активный. Удалять его при удалении всех других - тоже надо (не жалко, а он может остаться). Хотя вообще я не видел от такого тормозов никогда.

expl 14.11.2011 00:00

Цитата:

Хотя вообще я не видел от такого тормозов никогда.
Я тоже, потому что всегда отписываюсь :) А народ, говорит видел.

Vektor 14.11.2011 01:02

Тестируйте, 4раза onButtonCreate(_mcButton0,100,100);
1раз onButtonDelete(_mcButton0);
По вашим словам дожно быть 4шт( stage.addEventListener(MouseEvent.MOUSE_UP, onMouseEvent);)
Код AS3:

package {
        import flash.display.MovieClip;
        import flash.display.Stage;
        import flash.events.MouseEvent;
        public class Cbut extends MovieClip {
                private var _mcButton0:mcButton=new mcButton  ;
                private var _mcButton1:mcButton1=new mcButton1  ;
                private var _mcButton2:mcButton=new mcButton  ;
                private var _mcButton3:mcButton1=new mcButton1  ;
                private var _bDown:Boolean=false;
                private var _oDownButon:Object=new Object  ;
                //private var _iCounter:int=0;
                public function Cbut() {
                        // constructor code
                        onButtonCreate(_mcButton0,100,100);
                        onButtonCreate(_mcButton1,200,100);
                        onButtonCreate(_mcButton2,200,200);
                        onButtonCreate(_mcButton3,100,200);
                        onButtonDelete(_mcButton0);
 
                }
                private function onButtonCreate(But,x:int,y:int):void {
                        //trace(But as MovieClip)
                        addChild(But);
                        But.stop();
                        But.x=x;
                        But.y=y;
                        this.addEventListener(MouseEvent.MOUSE_OVER, onMouseEvent);
                        this.addEventListener(MouseEvent.MOUSE_OUT, onMouseEvent);
                        this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseEvent);
                        stage.addEventListener(MouseEvent.MOUSE_UP, onMouseEvent);
                }
                private function onButtonDelete(But:MovieClip):void {
                        But.removeEventListener(MouseEvent.MOUSE_OVER, onMouseEvent);
                        But.removeEventListener(MouseEvent.MOUSE_OUT, onMouseEvent);
                        But.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseEvent);
                        stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseEvent);
                        removeChild(But);
                        But=null;
                }
                private function onMouseEvent(event:MouseEvent):void {
                        //_iCounter++;
                        switch (event.type) {
                                case MouseEvent.MOUSE_OVER :
                                        if (_bDown&&_oDownButon==event.target) {
                                                _oDownButon.gotoAndStop(3);
                                        } else {
                                                event.target.gotoAndStop(2);
                                        }
                                        break;
                                case MouseEvent.MOUSE_OUT :
                                        event.target.gotoAndStop(1);
                                        break;
                                case MouseEvent.MOUSE_DOWN :
                                        //stage.addEventListener(MouseEvent.MOUSE_UP, onMouseEvent);
                                        _oDownButon=event.target;
                                        event.target.gotoAndStop(3);
                                        _bDown=true;
                                        break;
                                case MouseEvent.MOUSE_UP :
                                        if (!(event.target is Stage)) {
                                                event.target.gotoAndStop(2);
                                        }
                                        trace("Не работает")
                                        //stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseEvent);
                                        _bDown=false;
                                        break;
                        }
                }
        }
 
}


GBee 14.11.2011 01:19

У меня без stage ок было, может что-то не учел?

Код AS3:

private var _up:DisplayObject;
private var _over:DisplayObject;
private var _down:DisplayObject;
private var _disabled:DisplayObject;
public function Button()
{
        mouseChildren = false;
        addEventListener(MouseEvent.ROLL_OVER, mouseHandler);
        addEventListener(MouseEvent.ROLL_OUT, mouseHandler);
        addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler);
        addEventListener(MouseEvent.MOUSE_UP, mouseHandler);
}
 
private function mouseHandler(event:MouseEvent):void
{
        if(!enabled)
                return;
        switch(event.type)
        {
                case MouseEvent.ROLL_OUT:       
                        layerVisibles(true, false, false);
                break;
                case MouseEvent.ROLL_OVER:
                case MouseEvent.MOUSE_UP:
                        layerVisibles(false, true, false);
                break;
                case MouseEvent.MOUSE_DOWN:
                        layerVisibles(false, false, true);
                break;
        }
}
 
private function layerVisibles(up:Boolean, over:Boolean, down:Boolean):void
{
        if(_down)
                _down.visible = down;
        if(_over)
                _over.visible = over;
        if(_up)
                _up.visible = up;
        if(!up)
        {
                if((!_down && down) || (!_over && over))
                        _up.visible = true;
        }
}


-De- 14.11.2011 02:06

Vektor, вы эта, знаете, что ваш код делает вообще? %)
Я там мог ошибиться, да, с 4-мя, не зная, что такое But.
Из страшного
Во-первых, это не класс кнопки, похоже, а класс, который каким-то странным образом их содержит. Не советую так делать, морока.
Потом:
Код AS3:

this.addEventListener
...
But.removeEventListener //или везде But или везде this, определитесь
...
But=null;//убьёт только локальную переменную, эти ваши private var _mcButton... - не обнулятся


Wolsh 14.11.2011 02:46

Цитата:

На MOUSE_LEAVE можно не подписываться, MOUSE_UP в любом случае сработает.
Если бы срабатывал, я бы не подписывался. В том то и дело, что если нажать на кнопку, увести мышь за пределы окна флэшки и отпустить, потом завести в окно, нажать и завести на кнопку – окажется что isDown == true, то есть ап не был пойман.
Цитата:

ну кого реально волнует
Меня. Возможно, со стороны выглядит глупо ради такой редкой ситуации вводить новую сущность (стейдж) и соответственно новый потенциальный источник нестабильности/ошибок, но это как бы Prestige программиста и оставлять кляксы, извините, не спортивно. Именно из-за таких "да ну нафиг я буду с этим париться" порой так трудно выбрать себе стороннюю либу для проекта. И разве не по этой же причине возникла и эта тема?))) Не из-за того что кто-то сказал про симплбаттон "сойдет и так"?


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

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