sábado, 14 de marzo de 2009

MemeFX ... con Popup Menu (experimental)


Estuve haciendo algunos arreglos al experimento del menú flotante que desarrollé hace algún tiempo, y salvo algunos detalles, funciona sin problemas.

Acabo de subir el código de la biblioteca (memeFX), incluyendo este código y un demo, donde se aprecia como usar el menú flotante.

Para ver el demo (Java Web Start), haz CLICK AQUI

Para visitar el sitio web del proyecto, CLICK AQUI

Algo de código:

Primero, se crea un tipo de menú colgante... lo que puede incluir cambios a la apariencia del menú (colores, grosores, rotación, transparencia, esquinas redondeadas, etc.).


var popupCircle = PopupMenu{
corner: 20, padding: 8, borderWidth: 4,
opacity: 0.9, animate: true


content: [
MenuItem { text: "Animar circulo!",
callNode
: node },

MenuItem { text: "Mostrar nombre y posicion",
callPosId: positionId }

]
};

El tipo de función declarada para el Item (la función que ejecuta al ser seleccionado un item del menú), tiene que ver con los parámetros que retorna el menú al ser seleccionada la opción:

call = no retorna parametros, la función es declarada como:

function algo():Void { ... };

callId = retorna el ID del objeto sobre el que se utilizó el menú, la función es declarada como:

function algo(id:String):Void { ... };

callPos = retorna el MouseEvent que originó la aparición del menú. Permite, por ejemplo, obtener la posición del mouse al lanzar el menú (¿qué otros datos se pueden obtener de MouseEvent?). La función es declarada como:

function algo(e:MouseEvent):Void { ... };

callNode = retorna el Nodo sobre el que se utilizó el menú flotante. Permite manipular directamente el objeto (en este ejemplo, se anima el tamaño del círculo seleccionado). Si se quiere utilizar sobre un tipo particular de nodo, es necesario hacer un casting al tipo de objeto apropiado... ejemplo, si el tipo de objeto es un campo de texto: (node as SwingTextField).text="{node.id}" . La función es declarada como:

function algo(node:Node):Void { ... };

callPosId = retorna el MouseEvent que originó la aparición del menu y el ID del objeto sobre el que se utilizó (puede ser útil para saber en que parte del objeto se hizo click). La función es declarada como:

function algo(e:MouseEvent, id:String) { ... };

callPosNode = retorna el MouseEvent que originó la aparición del menu y el Nodo sobre el que se utilizó (puede ser útil para saber en que parte y sobre que objeto se hizo click). La función es declarada como:

function algo(e:MouseEvent, node:Node) { ... };

En este ejemplo agregaré dos círculos:

var circle1 = Circle {
id: "Cicle 1"
centerX: 100, centerY: 100
radius: 40, fill: Color.RED
};

var circle2 = Circle {
id: "Cicle 2"
centerX: 220, centerY: 300
radius: 80, fill: Color.YELLOW
};

Los ID son opcionales, pero pueden ser usados para reconocer sobre que objeto se lanzó el menú flotante (callId y callPosId).

A continuación, enlazo el menú con los círculos:

popupCircle.to(circle1);
popupCircle.to(circle2);

Se agregan las rutinas que serán ejecutadas por las opciones del menú (el código pudo ser incluido al definir el menú colgante).

function node(node:Node):Void {
Timeline {
repeatCount: 4
autoReverse: true
keyFrames: [
at (0s) {node.scaleX => 1.0;
node.scaleY => 1.0 }

at (0.2s) {node.scaleX => 1.4;
node.scaleY => 1.4}

]
}.play();
};

function positionId(e:MouseEvent, id:String):Void {
println("Mouse at {e.x},{e.y} over {id}");
}

Finalmente, se agregan los círculos y los menús al Stage:

Stage {
scene: Scene {
content: [
circle1,
circle2
PopupMenu.activateMenus()
]
}
}

No hay comentarios: