MetaCard y Revolution: Herramientas de autor multiplataforma para multimedia | ||
---|---|---|
Anterior | Capítulo 7. Texto | Siguiente |
Ya se han introducido los objetos de tipo campo de texto (field) en la la sección de nombre Campos de texto (field) en Capítulo 4, así que aquí abordaremos la utilización del texto pero como media: esto es, como soporte de elementos de efecto en la comunicación y como soporte de la información (documentos) y acceso a la misma.
Empecemos por algo sencillo. Este es un pequeño ejercicio práctico para introducir algunas propiedades del texto, como las fuentes de letra, el tamaño y otras propiedades del mismo. Se trata de mostrar el texto que contiene un campo de texto (el mío se llama "campDeText") más o menos centrado en la pantalla y sobre el que se podría montar unos créditos de cierre de una aplicación con un cierto aire de película haciéndolos desplazarse de arriba a abajo.
Bueno, pues simplifiquémoslo más aún: que los contenidos del campo de texto vayan rotando por filas en el campo de texto. Al fin y al cabo, nuestro interés se centra en mostrar la propiedad htmlText de un campo de texto como un posible constructor de apariencias para el texto. Esto es debido y de ahí su sencillez de aprendizaje, por la utilización de las familiares etiquetas de HTML utilizadas (algunas en demasía y fuera de sitio) en las páginas Web.
Bueno, queremos hacer algo similar a la Figura 7-1, en la que se ve un botón y, se intuye, un campo de texto. Todo ello en blanco sobre negro para que no se vea la ruptura con el fondo. Así se verá obligado a tocar alguna propiedad más ...
Todo el trabajo está en el código del botón, quien cada vez que es pulsado:
Inicializa el contenido de la propiedad htmlText. El contenido del campo de texto, en texto puro y duro, nunca es modificado. Sólo su presentación.
Baja una fila cada una de las que componen el texto y sube la última fila a la primera.
Asigna los valores de tamaño aprovechando el número de línea para ello. Observe que todo ello está encerrado entre una pareja de órdenes lock/unlock con el parámetro "screnn". Así la ventana no se refresca hasta que no se han hecho todos los cambios y se disminuye el parpadeo de la misma.
# # Botón "superText" # on mouseUp # Preparat, que vaig set the htmlText of field "campDeText" to empty # Pega-li la volteta al que hi ha set the contingut of field "campDeText" to \ the last line of the contingut of field "campDeText" & return & \ line 1 to (the number of lines of the contingut of field "campDeText" -1) of the contingut of field "campDeText" # Arregla tamanys put empty into field "valors" lock screen repeat with linea = 1 to the number of lines of the contingut of field "campDeText" set the htmlText of field "campDeText" to \ the htmlText of field "campDeText" & \ "<p><font size=" & quote & (linea + 8) + 3 & quote &">" & \ line linea of the contingut of field "campDeText" & \ "</font></p>" & return end repeat unlock screen end mouseUp
Así nuestra aplicación podría ir enviando los mensajes de mouseUp al botón superText que podría estar oculto y además ... Ejercicio, lo acabo de proponer allí, lo siento.
Ya tenemos el primero, veamos otra posibilidad para altererar la apariencia del texto. Siguiendo con la vena cinematográfica vamos a intentar reproducir el efecto de una película un poco más reciente que las que utilizaban el anterior efecto. En este caso ...
# # La tarjeta # global parar, ncols, nfiles on resizeStack set the lockLocation of field "campDeText" to true set the width of field "campDeText" to \ (the width of this card - ( 2 *the left of field "campDeText") ) set the height of field "campDeText" to \ (the height of this card - ( 2 *the top of field "campDeText") ) put round( 5 / 3 *(the height of field "campDeText" / \ (the effective textSize of field "campDeText" +\ the textHeight of field "campDeText"))) into nfiles put round ( 5 / 3 *(the effective width of field "campDeText" / \ the effective textSize of field "campDeText") ) into ncols set the htmlText of field "campDeText" to empty put empty into linea send "mouseUp" to button "botoRedimensionar" of this card end resizeStack # # fld "campDeText" # global parar, ncols, nfiles, volta on comença if parar = true then put 1 into volta exit "comença" else put volta + 1 into volta end if # Avançar alguna lletra blanca -- En lineOffset localitze la primera linea i, d'esta, el primer caracter blanc -- El patro es algo com -- "<font color=" & quote & "#FFFFFF" & quote & "><b>" & CARACTER & "</b></font>" -- NO, NO., NO SERVEIX: LA SEGUENT LINEA NO SAPS SI EN TE O NO, ... -- ACABARE LLEVANT-HO QUE EM DIFICULTA FER AVANÇAR LES LLETRES BLANQUES put the number of lines of the htmlText of me into lineaEscollida lock screen set the htmlText of me to \ line lineaEscollida of the htmlText of me & \ the line 1 to (lineaEscollida -1) of the htmlText of me &\ the line (lineaEscollida+1) to (the number of lines of the htmlText of me) of the htmlText of me unlock screen if (volta < 20) then send "comença" to me in (1000 - (volta * 50)) milliseconds end comença
Otro lugar donde el texto puede se de gran utilidad es en la presentación de ideas complejas u opciones en un programa. Vamos a crear un sencillo menú, de forma que al pasar el ratón por encima de las opciones de este, se produzca alguna modificación en la opción implicada. Esta deber ser tal que la haga resaltar sobre las demás y así el usuario reciba la realimentación de qué opción está a punto de escoger.
La interfaz propuesta (Figura 7-3y) está compuesta por un campo de textom en la parte superior, no editable y un grupo de botones que contienen las opciones del índice. En estos está el manejo del texto: cuando el botón recibe el foco (bien por que se ha activado con el teclado o bien por que el ratón pasa por encima de él) aprovechamos para modifcar el tamaño y el color del texto. Sólo muestro el código de uno de los botones por que todos hacen la misma tarea.
# #Botó Llançar els experiments de la tarjeta inicial # on focusIn repeat with nControl = 1 to (the number of buttons of the group "menuInici") if not( the short name of button nControl is the short name of me ) \ then send "focusOut" to button nControl of group "menuInici" end repeat set the textColor of me to green set the textSize of me to 34 end focusIn on focusOut set the textColor of me to black set the textSize of me to 14 end focusOut on mouseUp go to card (the short name of me) end mouseUp
No podemos aprovechar, en esta aplicación del menú, para concentrar el código en el grupo, puesto que necesitamos saber cuándo entra a un botón para resaltarlo y cuándo sale para restaurar su estado habitual.
Para terminar esta introducción, emprezaremos con un sencillo juego: replicando la estructura de un teletipo. Es, seguramente, la opción más clara para utilizar la orden type, aprovechando el código de ejemplo de la propia orden que se puede encontrar en MetaCard.
Figura 7-4. Enviando texto a un field con la orden type: un momento de la ejecución (izquierda) y final (derecha).
El interfaz puede responder a diseño que muestar la Figura 7-4. La idea central es ofrecer una ayuda visual a la utilización de una aplicación. En el caso actual, y sólo es un ejemplo, cuando se llega a esta tarjeta (se abre la pila o se circula hasta llegar a ella) se le recuerda la utilidad de aquel campo con un mensaje.
Cuando un campo de texto recibe el foco, se hace el objeto activo. Recibe un mensaje openFieldy, si es editable, permitirá las típicas acciones de edición habituales de estos. De manera general (es decir se aplica a cualquier objeto o a la tarjeta actual si no hay ninguno activo) el evento generado es focusIn, este es que recibiría un campo de texto bloquejado con locked fields. Veámoslo sobre un ejemplo del propio MetaCard:
on openField send "enterText" to me end openField on enterText choose browse tool focus on fld "Shape" type "Introduzca la 'contraseña'" end enterText
Nota: Si ha puesto en marcha el ejemplo, habrá observado que aunque seleccione el campo de texto para teclear algún texto no puede hacerlo. Esto es debido a que el control activo ha habido que cambiarlo al campo de texto que muestra el aviso. Para poder "actuar" en el campo de texto habrá que hacer algo más ...
Si se añade, al final del "enterText" una de las dos líneas comentadas en el código anterior entonces se generará un openField y se volverá a ejecutar este código, que volverá a enviar el foco al campo de texto y volvemos a empezar. Así que puede utilizar la orden lock para evitar que la siguiente orden genere ningún mensaje.
... lock messages focus on me ...
Por supuesto, la acción que hace type se podría haber hecho igualmente con put y ahí habría cabida para un número mayor de efectos. Pero vamos a dejarlo ahí, de momento, que para el poco código que nos ha costado no está mal y no hemos hecho uso de propiedades como typingRate que permitiría variar el efecto.
Como muestra de utilización de ficheros de texto y procesado de los mismos, vamos a realizar un acceso a un fichero que contenga la descripción de una serie de nombres de aplicaciones y su utilidad. Como ejemplo de esto se utilizarán los nombres y la funcionalidad de los programas que componen las utilidades Netpbm (creado a partir del Pbmplus de Jef Poskanzer) que (como dice en su README.gz) incluyen tanto la posibilidad de conversión entre un buen número de formatos gráficos, así como el empleo de unas cuantas operaciones básicas de procesado de imágenes.
El elevado número de estas utilidades, junto a la discontinua utilización de este conjunto de programas, me hace difícil tener siempre presente qué opciones están ya realizadas y si puedo simplemente encadenarlas con tuberías para realizar una acción más compleja. Además la posibilidad de ser utilizado por quien las desconoce aún más que yo me animó a crear un interfaz para encontrar la aplicación que realiza una cierta tarea y obtener la necesaria lista de parámetros con que invocarla.
Con lo que se propone hacer un interfaz que lliste todas las opciones y que se vaya reduciendo el número de estas conforme se defina la búsqueda del usuario. Decidida una opción se presentará esta con todo detalle. Esta última es la expresión de lo que aparece en las páginas del manual de cada orden. Así que la primera parte es conseguir ese fichero de texto, para ello ...
Aviso |
... para ello ... |
Y lo siguiente es probar, antes de ir demasiado lejos, así que vamos suponer que ya tenemos un fichero con líneas como:
pbmclean-flip isolated pixels in portable bitmap pbmlife-apply Conway's rules of Life to a portable bitmap pbmmake-create a blank bitmap of a specified size pbmmask-create a mask bitmap from a regular bitmap pbmpscale-enlarge a portable bitmap with edge smoothing pbmreduce-read a portable bitmap and reduce it N times pbmtext-render text into a bitmap pbmto10x-convert a portable bitmap into Gemini 10X printer graphics pbmto4425-Display PBM images on an AT&T 4425 terminal pbmtoascii-convert a portable bitmap into ASCII graphics pbmtoatk-convert portable bitmap to Andrew Toolkit raster object pbmtobbnbg-convert a portable bitmap into BitGraph graphics pbmtocmuwm-convert a portable bitmap into a CMU window manager bitmap pbmtoepsi-convert a portable bitmap into an encapsulated PostScript style preview bitmap ...
donde en cada línea se tiene la descripción de una utilidad separando su nombre de su descripción por un carácter dado, en nuestro caso el guión. El elemento que hará posible la selección de la utilidad correspondiente es una variación de la que permite buscar una orden o propiedad en el diccionario de MetaTalk. Copiado este elemento (esta subpila), el código tendrá que ser algo parecido a:
# # la pila 'tutorialNetPGM' # on openCard if the short name of this card is "inici" \ then send "mouseUp" to btn "carregarFitxerDescripcio" put empty into fld "cadenaABuscar" of group "buscar" end if end openCard on resizeStack send "resizeStack" to group "menuGroup" send "resizeStack" to group "barraDeMensatges" end resizeStack # # button "arregarFitxerDescripcio" on mouseUp hide group "buscar" set the loc of image "splash" to the loc of this card show image "splash" if there is a file "netPBM.txt" then put url "file:netPBM.txt" into fld "copia-netPBM.txt" else put the descripcions of this stack into fld "copia-netPBM.txt" lock screen send ("crear" && 1) to button crearTarjeta hide image "splash" show group "buscar" end mouseUp # card "inici" on openCard if the short name of this card is "inici" then hide group "paginaDeManual" show group "buscar" else -- hide group "buscar" show group "paginaDeManual" end if end openCard # # button "buscar" # cadenaABuscar on backspaceKey delete last char of me send "keyUp" to me -- pass "backspaceKey" end backspaceKey on keyUp lock screen put the descripcions of this stack into fld "resultatsBusqueda" filter fld "resultatsBusqueda" with ( "*" & the text of me & "*") set the vScrollBar of fld "resultatsBusqueda" to (the formattedHeight of fld "resultat sBusqueda" > the height of fld "resultatsBusqueda" ) set the hScrollBar of fld "resultatsBusqueda" to (the formattedWidth of fld "resultats Busqueda" > the width of fld "resultatsBusqueda" ) unlock screen end keyUp # # field "resultatsBusqueda" # on mouseDoubleUp if (the number of cards of this stack > 1) and \ (there is a card (the number of cards of this stack - \ (lineOffset(the selectedText, \ fld "copia-netPBM.txt" of card "Inici") - 1))) then put the first item of the selectedText go to card (the number of cards of this stack -\ (lineOffset(the selectedText, fld "copia-netPBM.txt" of card "Inici") -1)) else answer error \ "Recarrega la configuració des de el menu 'Fitxer' i reintenta esta operació" \ titled "[" & the short name of me & "]" end if end mouseDoubleUp on returnInField --enterInField send "mouseDoubleUp" to me end returnInField --enterInField # # button "crearTarjeta" # on crear i if i > the number of lines of fld "copia-NetPBM.txt" of card "inici" then unlock screen else set itemDelimiter to "-" put the first item of (line i of fld "copia-netPBM.txt" of card "inici") into \ fld "textBarraDeMensatges" create card put the first item of (line i of fld "copia-netPBM.txt" of card "inici") into fld "NAME" put the second item of (line i of fld "copia-netPBM.txt" of card "inici") into\ fld "SYNOPSIS" of group "paginaDeManual" set the script of this card to the script of card "inici" go to card "Inici" send ("crear" && i + 1) to me --in 10 milliseconds end if end crear
Este punto sirve para demostrar l'ús de les funcions de búsqueda en el texto. Además, hay que verlo como un paso previo al tratamiento de ficheros XML, desde MetaCard
La situación que vamos a abordar primero viene dada por aprovechar la escritura de la ayuda de una aplicación que realizaemos en un formato que haga posible su fácil conversión a cuantos formatos sea de interés ... En este caso hemos elegido HTML, del cual aprovecharemos su vertiente de estructurador de contenidos para localizar las partes que componen el documento y crear de manera dinámica un índice del documento (la ayuda en este caso).
Un documento HTML se puede ver como un árbol, en nuestro caso formado por apartados que vienen determinados por la aparición de ciertas etiquetas. Vamos a recorrer el archivo buscando etiquetas "h2" para crear de forma dinámica , en tiempo de ejecución, un índice de las secciones que forma la ajuda.
# # Pila # on openStack put url ("file:" & the mainStack of this stack & ".html") into fitxerAjuda if matchText( fitxerAjuda, ".<head>.<title>(.*)</title>.</head>.", varAux2 ) then set the title of this stack to varAux2 else set the title of this stack to (the mainStack of this stack & ".html") end if if matchText( fitxerAjuda, ".<body>(.*)</body>.", varAux2 ) then set the htmlText of field "contingutAjuda" to varAux2 if (the formattedHeight of field "contingutAjuda" > the height of field "contingutAjuda") \ then set the vScrollBar of field "contingutAjuda" to true end if send "carregarItems" to this card of this stack else answer error "Error al carregar el fitxer d'ajuda: ajudaPpal.html" end if end openStack on closeStack set the vScollBar of field "contingutAjuda" to false end closeStack
Y cuando ya es posible hablar de un fichero sólo queda ir buscando el inicio de las secciones que hemos decido marcan las etiquetas "h2" del fichero HTML.
# # Tarjeta # on carregarItems put url ("file:" & "ajudaPpal.html") into fitxerAjuda put empty into button "buscaText" repeat while matchText( fitxerAjuda, ".[^<]*<h2>(.[^<]*)</h2>(.*)", itemH2, restoFitxer ) put (itemH2 & return) after button "buscaText" put restoFitxer into fitxerAjuda end repeat end carregarItems
Para ir a cada uno de estos apartados, el botón desplegable que guarda el índice de las secciones del fichero de ayuda calculará el incremento que tiene que mover la barra de desplazamiento para situarse en el punto correspondiente, por ejemplo, de esta forma:
# # Botón "buscaText" # on menuPick quin set the scroll of field "contingutAjuda" to \ lineOffset( quin, the text of field "contingutAjuda") * the textHeight of field "contingutAjuda" end menuPick
La descripción que corresponda.
Examinaremos en este apartado la utilización de dos objetos desarrollados para el uso de esta tecnología como son XMLLibrary .
Y Altuit XML TreeView List Control.