Форум 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=150308)

demy 09.02.2011 17:47

События мыши и их перекрытие
 
Здравствуйте.
Вопрос, казалось бы, простой, но ответа так и не нашла.
Как сделать так, чтобы при слушателях, например, клика и MOUSE_DOWN - срабатывал либо клик, либо маус-даун?
Я сделала булевы переменные - мол, не надо, я зажала и двигаю, а не кликаю.
Код AS3:

private function moveButtonOn(event:MouseEvent) {
        moving = true;
        ...
}
private function fixTip(event:MouseEvent) {
        if(!moving && !deleting) {
            ...
        }
}

А все равно они срабатывают вместе и переменная не успевает смениться.
Подскажите, как исправить?

Bgg 09.02.2011 17:57

Воспользоватся одним обработчиком?
Код AS3:

private function mouseHandler(event:MouseEvent):void{
        if (event.type == MouseEvent.MOUSE_DOWN) {
                //
        }else if (event.type == MouseEvent.CLICK) {
                //
        }
}


samana 09.02.2011 18:06

Цитата:

Сообщение от Bgg (Сообщение 972034)
Воспользоватся одним обработчиком?

А ведь тут тоже оба события срабатывают.

Dukobpa3 09.02.2011 18:26

Повесить слушатель только на MOUSE_DOWN. Считать сколько милисекунд зажата кнопка, и если дольше положенного диспатчить клик. Ну или просто вызывать функцию обработчик клика.

demy 09.02.2011 18:32

Побаловалась с идеей:
Код AS3:

stage.addEventListener(MouseEvent.MOUSE_DOWN, onClick);
stage.addEventListener(MouseEvent.MOUSE_UP, onClick);
stage.addEventListener(MouseEvent.CLICK, onClick);
 
function onClick(event:MouseEvent) {
        var moving = false;
        if (event.type == MouseEvent.MOUSE_DOWN) {
                moving = true;
        }
        if (event.type == MouseEvent.MOUSE_UP) {
                moving = false;
        }
        if (!moving) {
                trace("Ухты!");
        }
}

Получается, что отпускание отменяет зажатие - и остается чистый клик.
Отсюда появилась извращенская идея с массивом отметок событий... но идея не сработала.
Параллельное выполнение... такое параллельное...

Нужно не только перекрыть MOUSE_DOWN, но и клик по окончанию перетаскивания - то есть перекрытие в обе стороны.
Вот как его реализовать - все еще без понятия...

samana 09.02.2011 18:37

А если подписываться и отписываться на нужные события?

demy 09.02.2011 18:49

При зажатии срабатывает только down;
при отпускании срабатывает up, click;
при клике срабатывают down, up, click.

Чего-то голова уже не соображает - как их организовать?

Вообще закрадываются подозрения, что поскольку разница между событиями перетаскивания и клика только в длительности
(down, ..., up, click vs down, up, click), придется как-то с этим работать... А таймер очень-очень не хочется.
Правда еще тут же возникает идея - задействовать MOUSE_MOVE - так мы отделим перетаскивание, если мышь
между зажатием и отпускание выдает MOUSE_MOVE.
Но сразу же понятно, что тогда я клик от движения уже не отделю.

И вот окажется, что мы сейчас велосипед изобретаем... =)

alatar 09.02.2011 18:50

Код AS3:

stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
 
private var moving:Boolean = false;
...
private function onMouseDown(event:MouseEvent):void
{
    stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
}
private function onMouseUp(event:MouseEvent):void
{
    stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
    if (!moving)
    {
        trace("click");
    }
    moving = false;
}
private function onMouseMove(event:MouseEvent):void
{
  moving = true;
}


Dukobpa3 09.02.2011 19:54

2 alatar - А если у нас не клик а длительное нажатие? Тогда вся теория с маусмувом накроется тазиком.

Код AS3:

package 
{
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.utils.getTimer;
 
/**
 * @author Dukobpa3
 */

        public class Main extends Sprite
        {
 
                private var counter:int = 0;
 
                public function Main():void
                {
                        if (stage) init();
                        else addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(e:Event = null):void
                {
                        removeEventListener(Event.ADDED_TO_STAGE, init);
                        // entry point
 
                        stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
                        stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
 
                        this.graphics.lineStyle(2);
                        this.graphics.moveTo(mouseX, mouseY);
 
                }
 
                private function onMove(e:MouseEvent):void
                {
                        this.graphics.lineStyle(2);
                        this.graphics.lineTo(mouseX, mouseY);
                }
 
                private function onDown(event:MouseEvent):void
                {                       
                        counter = getTimer();//засекаем время начала клика
 
                        trace("Мышь нажата");
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);//Это так, для демонстрации прикрутил, можно и не двигать.
 
                        event.updateAfterEvent();
                }
 
                private function onUp(event:MouseEvent):void
                {
                        counter -= getTimer();//засекаем конец этого нехитрого действия
 
                        if (-counter <= 500) {//если отпустили раньше чем через полсекунды - значит клик
                                trace ("Это был клик: " + String( -counter));
                                this.graphics.clear();
                        }
                        else {//иначе обрабатываем завершение движения мыши
                                trace("Это был маусМув");
                        }
 
                        stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
                }
        }
 
}

Добавлено через 4 минуты
А велосипед да. Помню месяца полтора назад это на форуме уже обсуждалось. Поиск по форуму может помочь...

Кстати и ответы там те же были:)) Если бы не лень, то дал бы ссылку. Поиск по форуму;)

alatar 09.02.2011 20:09

Цитата:

2 alatar - А если у нас не клик а длительное нажатие?
А с каких пор это перестало считаться кликом?

Dukobpa3 09.02.2011 20:13

Не перестало. Но официально и маусмув это тоже клик;) Клик считается по маусАп. Так и во всяких там дотнетах, и С++ билдерах, так же и во флеше.

Попробуй в винде тыцнуть в любую кнопку, не отпуская поводить по ней и отпустить - кнопка нажмется. А если поводить и вывести за пределы этой самой кнопки - то не нажмется. Думаю ты вкурсе этой мульки....

alatar 09.02.2011 22:41

И как это все согласуется с полусекундным интервалом? Или ты свято веришь, что не может быть людей неспособных за посекунды нажать и отпустить кнопку?
Цитата:

Попробуй в винде тыцнуть в любую кнопку, не отпуская поводить по ней и отпустить - кнопка нажмется. А если поводить и вывести за пределы этой самой кнопки - то не нажмется. Думаю ты вкурсе этой мульки....
Тыцнул, поводил, вернул, отпустил нажалась. И что? Эта "мулька" особенности конкретной реализации. Причем это не зависит от оси. В большинстве случаев (и во флеше, кстати, тоже), если пользователь зажал кнопку мыши и отпустил над кнопкой (не важно выводил он курсор за пределы кнопки между этими событиями) кнопка нажмется. Это поведение, опять же, связано с тем что у человека могут быть физические или неврологические недостатки.

Dukobpa3 10.02.2011 00:40

Цитата:

И что? Эта "мулька" особенности конкретной реализации.
То что это не мулька конкретной реализации, а мулька стандарта.

alatar 10.02.2011 00:53

Цитата:

То что это не мулька конкретной реализации, а мулька стандарта.
Я вам привел противоположное поведение. Ссылка на этот стандарт имеется? Или так — ОБС?

semenyakinVS 10.02.2011 01:12

Цитата:

Сообщение от Dukobpa3 (Сообщение 972103)
Попробуй в винде тыцнуть в любую кнопку, не отпуская поводить по ней и отпустить - кнопка нажмется. А если поводить и вывести за пределы этой самой кнопки - то не нажмется. Думаю ты вкурсе этой мульки....

Хм... Всегда думал, что это связано с тем, что событие на кнопки вешается onRelease.

Добавлено через 3 минуты
Кстати, по поводу событий, раз уж речь зашла...

Как лучше их ловить? Делать главного слушателя и остальным иметь на него ссылки? Или мудрствовать, сочиняя что-нибудь более громоздкое, и не пользоваться сверх нормы бритвой Оккама?

Dukobpa3 10.02.2011 03:59

Цитата:

Я вам привел противоположное поведение.
Не было там противоположного поведения в примере. Всё в подтверждение того что Клик срабатывает по маусАп.

Ссылок на стандарт нету. Есть и другие реализации. К примеру на мобилах нету правой кнопки - заменяют длительным нажатием. И в таком духе. Но тем не менее то что я (да и вы тоже) приводил в пример говорит об одинаковости этого момента по-умолчанию.

VitaliyKrivtsov 10.02.2011 05:20

Идея с отчетом времени не годится.
Можно, например, нажимая на стейдж (при этом ранее подписываемся на MouseEvent.MOUSE_UP, MouseEvent.CLICK, MouseEvent.MOUSE_DOWN) мы получим, что при клике менее чем пол секунды происходят все три событие в такое очередности:
MouseEvent.MOUSE_DOWN,
MouseEvent.MOUSE_UP,
MouseEvent.CLICK
То есть отчет по времени не универсален. Гарантии того, что вызовем нужный обработчик - нету никакой.
И по ходу идея alatarа вполне решает эту проблемку.

alatar 10.02.2011 10:50

Цитата:

Всё в подтверждение того что Клик срабатывает по маусАп.
К чему это сказано? Я где-то говорил противоположное?
Цитата:

Ссылок на стандарт нету.
Тогда не надо утверждать, что есть некий стандарт.

demy 10.02.2011 12:03

О!, спасибо вам огромное!
alatar, этот вариант как раз подойдет, спасибо!
Все-таки очень не хотеть таймер...


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

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