DevSecOps

14 mai, 2007

Adobe Flash CS3 ActionScript 2.0 – mx.events.EventDispatcher

Publicidade

Para acompanhar este artigo, é necessário conhecer o método de trabalho de componentes built-in do Macromedia Flash MX 2004 (ou superior). Nosso objetivo será executar ações distintas no mesmo evento através de listeners. Desenvolver componentes customizados com a mesma arquitetura de componentes da Adobe, recebendo eventos através de listeners.

Arquivo Final

Conteúdo

O modelo de eventos recebidos pelos componentes da Adobe é diferente do modelo padrão de desenvolvimento que a maioria dos usuários do Flash adota. Ao invés do próprio objeto verificar o evento, quem faz isso é uma instância da classe Object. Explicando melhor:

Em algums momentos você pode querer detectar uma mudança complexa de evento do componente, ou mesmo construir componentes feitos sob encomenda, ou métodos mais práticos para a conclusão de projetos mais longos. Frequentemente desenvolvedores e designers da ferramenta Flash recorrem ao uso de variáveis globais ou de laços (for, for..in, while, do..while) complexos a fim de verificar repetidamente para ver se há mudança de evento no componente com sucesso. É mais simples especificar seus eventos usando o modelo de listeners para ouvir o evento que desejamos, pois o mesmo listener pode ouvir a dezenas de objetos que contém o mesmo evento.

Vamos discutir algo simples sobre a EventDispatcher, mas que engloba o conceito principal dos listeners.

Começaremos com a criação da classe:

class TesteEvent extends MovieClip {

public function TesteEvent() {
super();
}

private function onPress():Void {
this.startDrag(false);
this.swapDepths(this._parent.getNextHighestDepth());
this.onMouseMove = function():Void {
updateAfterEvent();
};
}

private function onRelease():Void {
this.stopDrag();
delete this.onMouseMove;
}

}

Salve o arquivo como TesteEvent.as.

Até aqui tudo normal. O que vamos fazer agora é inserir os eventos para onPress, onMouseMove e onRelease. Porém, não utilizaremos diretamente esses eventos da classe MovieClip, e sim, inserir retornos para cada evento, utilizando a criação interna para os futuros listeners:

Passo 1:

Importar a classe EventDispatcher.

Passo 2:

Criar os eventos para disparar, cadastrar e remover listeners.

Passo 3:

Inserir dentro de cada evento da classe MovieClip o callback (função de retorno), que nesse caso será um disparo na inicialização do evento listener para cada evento ocorrido.

O código agora fica assim:

import mx.events.EventDispatcher;
class TesteEvent extends MovieClip {
//criamos os objetos para cada disparo de evento
private var evtObj1:Object = new Object();
private var evtObj2:Object = new Object();
private var evtObj3:Object = new Object();

public function TesteEvent() {
super();
//inicializamos a funcionalidade de disparo a ele mesmo (nossa própria classe)
EventDispatcher.initialize(this);
}

private function onPress():Void {
//adicionamos o alvo e o tipo de evento
evtObj1.target = this;
evtObj1.type = "pressed";
//mandamos disparar, lembrando que essa ação só é criada quando o usuário pressiona o mouse no movieclip em questão, já que estamos no evento onPress
this.dispatchEvent(evtObj1);
this.startDrag(false);
this.swapDepths(this._parent.getNextHighestDepth());
this.onMouseMove = function():Void {
//adicionamos o alvo e o tipo de evento
evtObj2.target = this;
evtObj2.type = "moved";
//mandamos disparar, lembrando que essa ação só é criada quando o usuário pressiona o mouse no movieclip em questão, já que estamos no evento onMouseMove
this.dispatchEvent(evtObj2);
updateAfterEvent();
};
}

private function onRelease():Void {
this.stopDrag();
delete this.onMouseMove;
//adicionamos o alvo e o tipo de evento
evtObj3.target = this;
evtObj3.type = "released";
//mandamos disparar, lembrando que essa ação só é criada quando o usuário pressiona o mouse no movieclip em questão, já que estamos no evento onRelease
this.dispatchEvent(evtObj3);
}

//função de disparo de eventos
private function dispatchEvent() {
}
//função de cadastro de listeners
function addEventListener() {
}
//função de remoção de listeners
function removeEventListener() {
}
}

Salve-o novamente e abra um documento novo, salvando-o na mesma pasta da classe para testarmos.

Crie um movieclip qualquer, aplique o component definition e o linkage dessa forma:

Adicionei um componente (Window – Components) TextArea ao palco para que possamos observar visualmente oque está acontecendo. O nome de instância é recebe_txt.

Crie um layer de ActionScript e adicione o seguinte código:

var listener:Object = new Object();
listener.pressed = function(evtObj:Object) {
recebe_txt.text += evtObj.target+": pressed"+newline;
recebe_txt.vPosition = recebe_txt.maxVPosition;
};
listener.moved = function(evtObj:Object) {
recebe_txt.text += evtObj.target+": moved"+newline;
recebe_txt.vPosition = recebe_txt.maxVPosition;
};
listener.released = function(evtObj:Object) {
recebe_txt.text += evtObj.target+": released"+newline;
recebe_txt.vPosition = recebe_txt.maxVPosition;
};
for (var i in this) {
if (this[i] instanceof TesteEvent) {
this[i].addEventListener("pressed", listener);
this[i].addEventListener("moved", listener);
this[i].addEventListener("released", listener);
}
}
recebe_txt.editable = false;

Crie quantas instâncias quiser do nosso componente TesteEvent, todos executarão da mesma forma, já que um loop adiciona o listener à todos os componentes desta classe.

Observe que agora nosso componente tem o evento declarado direto no objeto listener, e que os componentes visuais só recebem esse evento quando cadastrados pelo método addEventListener(“evento”, listenerObj).

Caso queiramos remover algum evento, podemos utilizar: mc.removeEventListener( “evento”, listenerObj).

Espero que tenham gostado.

Abraços e até a próxima!

Download dos arquivos