MetaCard y Revolution: Herramientas de autor multiplataforma para multimedia | ||
---|---|---|
Anterior | Capítulo 5. Otros elementos | Siguiente |
Este es un periférico habitual de nuestro trabajo con un computador. La utilización de interfaces gráficas hace posible tareas con un una alta componente visual y el ratón es un medio para que el usuario pueda señalar una posición en la ventana. Hemos utilizado mucho el evento mouseUp para hacer que un control, señalado físicamente con el ratón de manera arbitraria por el usuario o por que se le ha enviado el evento por la aplicación, haga su tarea.
Una de las facetas más interesantes de las órdenes asociadas con el ratón es choose: puede hacerse su propia paleta de herramientas o utilizarlas para crear en la ejecución de su aplicación un botón o pintar un área con el aerosol (spray). Aquí revisaremos las posibilidades de actuar conforme el ratón se mueve por la pantalla, o mejor dicho por la ventana de nuestra aplicación. Básicamente utilizaremos las coordenas de este para realizar algún tipo de actividad. Por ejemplo, podríamos mover un objeto que no està dentro de la ventana que define la pila:
move button "accio" to the mouseLoc
También es posible ocultarlo, moverlo y como haremos en diferentes ocasiones cambiar la apariencia del mismo. Esto último no tanto para lucirnos sino para informar al usuario de que se está realizando una tarea (que está ocupada la máquina aunque no se vean resultados en pantalla) o que está en disposición de empezarla. Muchas de estas tareas se realizan con los cursores que incorporan las herramientas y así hay definidas una serie de identificadores estándar par las situaciones habituales, tal como reza en la ayuda de MetaCard: none, arrow, busy, clock, cross, hand, iBeam, plus, watch y help
Nota: Pero recuerde que esas constantes son sólo identificadores a imágenes de una subpila de MetaCard. Así que, si de verdad lo necesita, puede importar una imagen, ocultarla y utilizar el
id
de las propiedades de esta para asignarselo a la propiedad cursor. ¡Haga la prueba!
Centrándonos en mover cosas con el ratón, en muchos lenguajes existen las órdenes drag o grab. Aquí también, pero hay que tener una cosa presente al respecto de utilizarlas:
grab es una forma sencilla de "enganchar" un objeto. Y, si lo utiliza como dice la ayuda, es efectivo para acciones en que nada haya que hacer mientras se mueve el objeto. Sólo esperar a que lo suelte para ver dónde lo deja caer.
drag (de forma parecida a click) se utiliza para simular que se actua sobre el ratón, moviéndolo de un punto a otro o que se genere un evento en una cierta posición. Esto lo hace interesante para crear animaciones en la que el cursor se haya de mover (podemos alterar su velocidad y otras cuestiones, como puede ver en la ayuda). Además, nada puede hacerse mientras el ratón se desplaza con la orden drag.
Hemos hecho ya estas acciones y las haremos con otras órdenes. De hecho, con send podemos generar esos eventos sobre un determinado objeto en pantalla sin preocuparnos (ni importarnos) su posición concreta en pantalla; de hecho puede estar fuera de la ventana u oculto y funcionará igual. Así que nosostros emplearemos, mayormente, la combinación mouseMove/movepara nuestras acciones.
Con lo que él código más básico es el asociado al evento mouseMove que recibe dos parámetros, las coordenas actuales del ratón y en que hay que mover el propio objeto a la posición identificada por esos parámetros, para lo que hay que recomponer la definición de un punto en pantalla para MetaTalk. Esto es, algo como:
on mouseMove x, y move me to x, y end mouseMove
De modo que, aunque haya varios controles con este código, sólo aquel sobre el que se posiciona el ratón recibirá este evento y, como lo trata, no llega a nadie más. Pruébelo, copie este código en dos botones, imágenes, ... y pruebe a moverse despacio sobre uno de ellos, pasar por encima del otro, salirse rápidamente de aquel sobre el que esté, ...
Compliquemos un poco el tema: vamos a mover un objeto y actuar al mismo tiempo. Para ello utilizaremos una pila como la que muestra la Figura 5-5. Allí tenemos cuatro objetos (botones, aunque podría haber sido cualquier otro) que queremos mover. Al mismo tiempo iremos mostrando si estamos encima o no de alguno de los otros botones, modificando la propiedad de visibilidad del borde de los controles. Utilizaremos threeD que hará cambiar la apariencia de resaltado de un botón, aunque otras opciones son posibles. Esto se realizará mientras esté pulsado el botón del ratón y cuando se suelte mostraremos un mensaje en la "Message Box".
Para no tener demasiado ocupado al sistema, sólo nos preocuparemos de hacerlo cuando se haya escogido un control: cuando se haya pulsado sobre él con el ratón. Como la acción (el código) es común para una serie de controles una opción que ahorra y concentra el código en un sólo punto es agruparlos en un grupo (group). Este puede identificar al objeto sobre el que recae la acción con la función target).
Cuando corresponda, haremos uso de la información de la posición del ratón para llevar hasta allí el control seleccionado. En ese momento, aprovechamos para comprobar si estamos encima de alguno de los controles del grupo (sin distinguir el tipo de los mismos). La estrategia empleada identifica sólo uno de los controles. Para ello nos quedaremos con el número más bajo y cuando se compruebe que se ha escogido ya un destino se obviarán los demás. Este es el código empleado para ponerla en práctica:
# # Grupo "botons" # local varAux, font=-1, desti=-1, i, j on mouseDown put the number of target into font end mouseDown on mouseMove x y put -1 into desti # No mes que mos preocupem quan cal fer-ho: # has triat un dels botons del grup (no el grup) i estas en ella. if (font <> -1) and \ (the number of the target is font) and \ (the target is not me) \ then move the target to x,y # I senyala damunt de qui consideres que estas repeat with i = 1 to the number of controls of me put the long time &":" && "font=" & font && "desti=" & desti &&\ "en" && i & "intersect?" & ( intersect(target, btn i) ) \ into line i of fld "eixida" # Si estem seguint al que toca: al font, ane'm b´e # Si intersecta en mes d'un te quedes en el de numero mes baix, en quan # 'desti' tinga un valor <> '-1' tots els demes ja no importa si intersecten if (the number of target <> i) and (desti = -1)\ then set the threeD of btn i to not( intersect(target, btn i) ) if (intersect(target, btn i)) then put i into desti end if else set the threeD of btn i to true end if end repeat end if end mouseMove on mouseUp put the long time &":" && "font=" & font && "desti=" & desti put -1 into font end mouseUp
Si se desea observar todas las coincidencias habrá de eliminar la restricción de:
(desti <> -1)
Otro ejemplo que puede ser de interés es la construcción de una banda elástica o de goma que permita identificar un área de, por ejemplo una imagen, con intención de señalar el área de interés de la misma donde aplicar un determinado proceso. Así que el contexto es el de una pila donde se encuentra un objeto de tipo image y sobre el que, a voluntad del usuario, se hará visible la selección de un área rectangular de la misma utilizando el ratón. Cuando este pulse un botón se inicia el proceso, que durará mientras lo mantenga pulsado y acabará cuando lo levante.
Parece que todo el código de la imagen gira en torno al evento mouseMove y el conjunto de coordenas que este nos devuelve utilzarlas para pintar un rectángulo, execpto en los casos de incio y fin de la actividad, así que podemos pensar en algo como:
# # Imagen "gImatgeOriginal" # on mouseDown send "bandaActiva" to graphic "bandaElastica" end mouseDown on mouseUp send "bandaInactiva" to graphic "bandaElastica" end mouseUp on mouseMove x, y send ("actualitzaBanda " & x & "," & y) to graphic "bandaElastica" end mouseMove
Dejando la responsabilidad del trabajo en el gráfico, quien debe mantener actualizadas las coordenas asignadas a su área de trabajo. Seleccionando el gráfico con el icono Graphic tool (rectangle) el resto puede ser sencillo:.
Esta lista de acciones se puede implementar como:
# # Gráfico "bandaElastica" # local x0, y0, \ x1, y1, estesNoFanFaltaPerAraComprobahhoooo,\ seguintLaBandaElastica on bandaActiva put the first item of the mouseLoc into x0 put the second item of the mouseLoc into y0 set the rectangle of me to x0,y0,x0,y0 put true into seguintLaBandaElastica end bandaActiva on bandaInactiva put false into seguintLaBandaElastica put the rect of me end bandaInactiva on actualitzaBanda x, y if (seguintLaBandaElastica) then \ set the rectangle of graphic "bandaElastica" to \ x0,y0,\ min( the third item of the rect of image "gImatgeOriginal", x), \ min( the fourth item of the rect of image "gImatgeOriginal", y ) end actualitzaBanda
Sólo un único detalle final: puesto que es una cuestión que se utiliza como interfaz para el usuario, hay que mantener a este informado de lo que se hace. Así que será interesante saber que sobre esa imagen sucede "algo": cambiaremos la forma del cursor para este caso, utilizando los eventos que nos indican que se entra o se sale del área de trabajo de un objeto. El código se añade al ya existente de la imagen, antes o después del anterior y es de la forma:
# # Imagen "gImatgeOriginal" # on mouseEnter set the lockCursor to true set the cursor to cross end mouseEnter on mouseLeave set the lockCursor to false end mouseLeave