Construcción de un menú

Este es un elemento usual en las aplicaciones donde se agrupan las acciones que puede realizar una aplicación. En MetaCard se puede realizar como un control complejo, en el sentido de que es un grupo de controles: son varios botones dispuestos de forma ordenada, de modo que se puede controlar su aspecto resaltado, alinearlos y utilizar la capacidad de un botón de mostrar "menús desplegable" para visualizar sus contenidos y permitir que el usuario escoja entre ellos. Vamos a partir del asistente que incorpora MetaCard para su realización y sobre aquel se introducen un par de modificaciones para hacer del control un elemento más versátil. Para empezar, utilizaremos la opción de la "Menu Bar" Tools|Menu Builder que nos ofrece un formulario como el que muestra la Figura 5-4a.

Figura 5-4. Creación de un menú: pantalla inicial del asistente ejecutado a partir de la opción de la "Menu Bar" Tools|Menu Builder.

a)b)

c)d)

Sobre esta plantilla inicial, puede modificar los elementos (tanto en número como en orden) que aparecen, así como aprovechar para cambiar el idioma de los textos que muestran o de las combinaciones de teclas que se utilizarán, así la Figura 5-4b, muestra un momento de la edición de estos y el resultado que se genera al pulsar sobre la opción Build se puede ver en la Figura 5-4c.

Una pequeña caja de mensajes nos recordará que hay que salvar la pila para guardar estas modificaciones y que ya ha puesto todos los elementos en su sitio. Se puede observar la estructura del grupo de controles generados en la Figura 5-4d. Todos ellos están accesibles mientras se edita la pila, como cualquier otro control que hayamos construido. Además se puede observar que ya hay código incluido en los elementos que se han dispuesto de forma automática.

Habrá observado el lector que, junto al texto de las opciones, aparecen caracteres como el ampersand ("&") , la barra ("/"), o un guión ("-"). Puede revisarlos después en la pestaña Extras de las propiedades del botón. Estos elementos están comentados, junto a otros, en menu items del Help | Index de la "Menu Bar".

Su misión es que el teclado pueda llegar, y además con rapidez, a los diferentes elementos del interfaz. No olvide que un usuario experto es más rápido con el teclado que el ratón escogiendo opciones o herramientas. Estos caracteres "especiales" pueden aparecer en cualquier lugar de una línea y se utilizan, de manera resumida, para:

Así, utilizando la situación de la entrada de menú vista en la Figura 5-4b, se puede encontrar que dada la especificación siguiente:

&Obrir.../O
-
ei&Xir/X
                      

La opción primera Obrir se pueda ejecutar directamente con las teclas Ctrl+Oo Ctrl+o. Así como también habiendo desplegado el menu de Fitxer, al que puede acceder con la combinación de teclado Alt+f, sin más que pulsar la letra resaltada: o

Con esto, ya tiene disponible un grupo de controles que implementan una barra de menús en su aplicación, personalmente debo añadir dos aspectos a esta cuestión

Así que acabo haciendo una serie de ajustes como los que se muestran a continuación, donde veremos cómo se pueden realizar estas modificaciones propuestas, para ver que tenemos todo el control sobre los objetos, como siempre; pero también para recordar el envío de mensajes y el paso de mensajes en la jerarquía de objetos que componen una aplicación. El primero de los cambios es que atañe a simplificar el código existente, por ejemplo veamos la opción Fitxer:

on menuPick which
  switch which
  case "Obrir..."
    break
  case "eiXir"
    break
  end switch
end menuPick
                   

Si fuera necesario hacer crecer el número de opciones o el código asociado a las mismas, es más conveniente separar el trozo de código de cada opción en un paso hacia la organización del mismo. Mi propuesta es: crear botones con el nombre de las opciones, de esta forma puedo probar el comportamiento del código de forma independiente y cuando esté conforme se ocultan a la vista del usuario. Con lo que el código anterior se puede reducir a:

on menuPick which
  send "mouseUp" to button which
end menuPick
                   

Respecto a la segunda modificación, pruebe de momento a redimensionar la pila y verá a lo que me refiero. El control no se reescala a lo ancho de la ventana y las opciones se mantienen siempre reunidas a la izquierda. Y no es que no haya dispuesto código para hacer parte de esta labor el propio asistente, pero sucede que no llega el evento resizeStack al control que lo contiene: el grupo "menuGroup". Podemos sustituir el código de la tarjeta que, inicialmente vacío hace que MetaCard sugiera un evento de openCard, por el de resizeStack, por que al visitar la ayuda que sobre este evento podemos consultar con el botón secundario del ratón sobre la palabra, vemos que este evento se envia "a la tarjeta actual de la pila redimensionada"

Aunque se pueden utilizar otras soluciones, mi propuesta sigue siendo la de concentrar código en los objetos correspondientes y tener que reescribir lo menos posible. Así que me llevo a la tarjeta la generación del evento (con el mismo nombre, claro ¿por qué no?) hacia el grupo de controles y sigo manteniendo la propagación de este evento en la jerarquía, por si la propia pila hiciera o tuviera que hacer algún otro proceso posterior:

on resizeStack
  send "resizeStack" to group "menuGroup"
  pass resizeStack
end resizeStack
                    

Ahora, la pincelada final: hay que limpiar el código original y hacer que el botón de ayuda aparezca a la derecha. Esto se puede conseguir con un comentario y la última instrucción que añado al objeto "menuGroup":

 
on resizeStack
  set the lockLocation of me to true
  set the width of me to the width of this card
  set the width of button "menuButton" of me to the width of me - 6
  set the left of button "menuButton" of me to 4
  #  pass resizeStack

  set the right of button "Ajuda" of me to (the right of me - 4)
end resizeStack
                    

Y no olvide que sólo le han asistido en una tarea compleja, este nuevo control sigue siendo de su entera disponibilidad y propiedad. Esto quiere decir que puede modificarlo a posteriori e incluso en tiempo de ejecución.

Sugerencia: Le propongo que realice un menú en el que la opción de "Editar" sea diferente para cada tarjeta de la aplicación y que la lleve a cabo en una sencilla aplicación con dos o más tarjetas. A mí, la solución que se me ocurre, está en función del código de la tarjeta, que utiliza su propio nombre para hacer visible y ocultar el botón que la define.