Me envían un correo diciéndome que tienen un menú con diversos botones y les gustaría que al momento de recibir el evento MouseEvent.CLICK que este incluya parámetros propios para así poder identificar el botón que fue.
Esta no es una buena planificación, pero en todo caso me parece un buen ejemplo para hablarles de el tema de custom Events.
El código que aquí presento es únicamente para mostrarles el ejemplo pero NO se los recomiendo ya que tiene distintos problemas de buena programación así como leaks de memoria.
Creemos nuestros menú:
Código :
import flash.display.MovieClip; import flash.display.Graphics; var total:uint = 3; var boton:MovieClip; var g:Graphics; for(var i:uint=0;i<total;i++){ boton = new MovieClip(); g = boton.graphics; g.beginFill(0xFF0000); g.drawRect(0, 0, 100, 80); g.endFill(); boton.y = 100; boton.x = (i * 110) + 100; addChild(boton); }
En este ejemplo si agregamos un addEventListener al botón no vamos a poder alcanzarle nuestros propios parámetros que de hecho es el indice del botón en el menú siendo 0 el primero.
La solución es crear nuestro propio tipo de MovieClip:
Código :
package { import flash.display.MovieClip; public class MiPropioMC extends MovieClip { public function MiPropioMC(){ super(); } } }
Teniendo esto podemos crear instancias de MiPropioMC en vez de un MovieClip pero aun no solucionamos el tema del parámetro en el evento.
Primero hay que crear el evento:
Código :
package { import flash.events.Event; import flash.events.MouseEvent; public class MiPropioEvent extends MouseEvent { public static const CLICK:String = "mipropio_click"; public var miIndice:uint; public function MiPropioEvent(type:String, indice:uint /*los demas parámetros no los vamos a utilizar en esta oportunidad*/) { miIndice = indice; super(type); } override public function clone():Event { return new MiPropioEvent(type, miIndice); } } }
Luego modifiquemos nuestra clase del MovieClip:
Código :
package { import flash.display.MovieClip; import flash.events.MouseEvent; public class MiPropioMC extends MovieClip { public var indice:uint; public function MiPropioMC() { super(); addEventListener(MouseEvent.CLICK, miDispatcher); } private function miDispatcher(e:MouseEvent):void { dispatchEvent(new MiPropioEvent(MiPropioEvent.CLICK, indice)); } } }
Ya con esto tenemos, ahora nada mas nos queda modificar nuestro menú:
Código :
import flash.display.Graphics; var total:uint = 3; var boton:MiPropioMC; var g:Graphics; for(var i:uint=0;i<total;i++) { boton = new MiPropioMC(); g = boton.graphics; g.beginFill(0xFF0000); g.drawRect(0, 0, 100, 80); g.endFill(); boton.indice = i; boton.y = 100; boton.x = (i * 110) + 100; boton.addEventListener(MiPropioEvent.CLICK, mandaTrace); addChild(boton); } function mandaTrace(e:MiPropioEvent):void { trace (e.miIndice); }
Eso es todo.
¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.
Por chiste el 19 de Febrero de 2009
No se como hago, pero me complico en las cosas simples y resuelvo las complejas con facilidad. Parece que a ti te pasa igual, porque la solución que me propones tiene 2000 lineas mas que la mia ja ja ja ja ja ja (claro que estas dibujando los botones y todo eso).
Saludos
Por fernando el 19 de Febrero de 2009
Lo que me gusta de este foro es que siempre mis posts como orden y formato son una mierda pero cada vez que lo visito mis posts estan mas nice jejeje
Para el que se tome el trabajo, gracias!
Por fernando el 19 de Febrero de 2009
ASU!
Por m33toh el 20 de Febrero de 2009
Estoy utilizando un cursor personalizado, no es un cursor con dibujito diferente, sino es un movieclip de 1x1px cuya posicion es diferente, pero relativa a la posicion del "cursor real", el cual es evaluado por un hitTest dentro de un bucle para comprobar si alguna instancia de "boton" esta haciendo contacto con el.
Se me ocurre que la forma mas ordenada es usando eventos personalizados, pero para serte sincero, no tengo idea de como lograrlo.
Por fernando el 20 de Febrero de 2009
Por m33toh el 20 de Febrero de 2009
Por M@U el 21 de Febrero de 2009
¿No bastaría con asignar dentro del loop que construye al menú un id a cada botón (name) y detectarlo a partir de event.target.name propio de MouseEvent.MOUSE_DOWN?
Son solo un par de lineas extra que harían lo mismo que tu evento creado.Por tufik2 el 22 de Febrero de 2009
var boton:MovieClip;
var g:Graphics;
for(var i:uint=0;i<total;i++){
boton = new MovieClip();
g = boton.graphics;
g.beginFill(0xFF0000);
g.drawRect(0, 0, 100, 80);
g.endFill();
boton.y = 100;
boton.x = (i * 110) + 100;
//++ Agregamos el nuevo codigo
boton.name = "boton"+i;
boton.addEventListener(MouseEvent.CLICK, BotonClick);
//--
addChild(boton);
}
function BotonClick(event:MouseEvent):void{
trace(event.target.name);
}
Por tufik2 el 22 de Febrero de 2009
boton.name = "boton"+i;
boton.addEventListener(MouseEvent.CLICK, BotonClick);
function BotonClick (event:MouseEvent):void{
trace(event.target.name);
}
Es facil, ¿no?
Por fernando el 22 de Febrero de 2009
Al final es un ejemplo de eventos propios y definitivamente no es un tip de como generar un menu.
Por M@U el 22 de Febrero de 2009
O puedes crear un Vector bidimensional en el cual para el primer nivel asignas los nombres de los elementos, y para el segundo añades el indice. Al hacer click detectas el nombre de instancia de lo que has pulsado, utilizas esta para buscar dentro del Vector, subes un nivel y ahí estará nuevamente el indice.
Por fernando el 22 de Febrero de 2009
jejeje lo del substring funcionaria y nadie dice que no.
Repito, este es un ejemplo de "incluir parámetros propios en los eventos de Actionscript 3" y no "como devolver el indice de un botón".
Además un substring is shitty programming asi que no me vengan que esos hacks no son buenos.
En fin... también cuando quieren verle 3 pies al gato...
Por eparada el 22 de Febrero de 2009
Lo que resolvimos fue usar una función intermedia. Aunque también es posible agregar una propiedad al vuelo a los MC y ya con eso hacer referencia al parámetro en mi caso un String que recibía un constructor de un URLRequest.
Si me permites un comentario creo que te viste muy Flexer para un problema Flasher, o para no despertar polémica con esto creo que te viste muy Pro para algo más Light
Por eparada el 22 de Febrero de 2009
Por M@U el 22 de Febrero de 2009
Como sea, muestras una buena manera para pasar (en este caso indices) parámetros a través de un evento. Felicidades es un muy buen Tip.
Por cierto, ¿ya probaste que el código de arriba funcione?
Por fernando el 23 de Febrero de 2009
Utilizar un substring soluciona el problema pero no es buena programación, utilizar el indice como nombre sin concatenarlo tampoco ya que perderias el data type de este.
Ya me dieron una idea para un proximo articulo. Thnx!
Por fernando el 23 de Febrero de 2009
Por M@U el 23 de Febrero de 2009
Ooh, y sin duda decir que tienes un compilador mental tiene mucho mas éxito con las chicas que admitir que si lo probaste.
Por fernando el 23 de Febrero de 2009
Y pues no se con que chicas sales tu pero con las que yo salgo no saben de compiladores...
Por Eliseo2 el 23 de Febrero de 2009
Por fernando el 23 de Febrero de 2009
De verdad que es estresante. =/
Por eldervaz el 23 de Febrero de 2009
sino usaria
Código :
Por Eliseo2 el 24 de Febrero de 2009
Volviendo al problema, creo que la mejor solución es extender la Clase button y hacerla dynamic. Con eso ya funcionamos como "toda la vida"
Por fernando el 24 de Febrero de 2009
A mi parecer ninguna clase de flash deberia ser por defecto dinámica ya que pierde todo sentido de type checking y puede hacer que el codigo sea un desmadre.
Por mas que MovieClip sea dynamic yo si generaría una clase propia con mi propiedad asi tengo mas control por lo que mi clase contiene.
No siempre la mejor solución es la solución fácil lamentablemente.
Por Eliseo el 24 de Febrero de 2009
Código :
Aunque coincido contigo en que lo suyo sería no hacer nuestro CustomButton dinámico sino crear unas funciones getter/setters
Respecto a que ninguna clase de flash debería ser por defecto dinámica, creo que sólo lo es la clase MovieClip. La verdad es que yo hubiera sugerido a Adobe que creara sus clases con la propiedad "arg", p.e. para poder usarla a convenir, pero ya es otro tema.
Por wawi el 10 de Marzo de 2010