Por omisión macOS añade al menú Ventana una serie de opciones realmente interesantes y que se han visto especialmente potenciadas en las últimas versiones del sistema operativo, tales como dividir el uso de pantalla, múltiples opciones para posicionar la ventana en diferentes ubicaciones de la pantalla (mitad superior, inferior, izquierda, derecha, etc.), o bien enviarla a la pantalla de cualquiera de los iPad detectados y que estén en la misma red local; esto es, la capacidad de utilizar la pantalla de tu iPad como segunda pantalla del Mac. Añadir dichas opciones al menú “Ventana” de tus apps macOS creadas con Xojo es realmente sencillo… mediante el uso de Declares.
Además, el hecho de añadir estas opciones a tu app significará que el usuario verá el mismo conjunto de opciones que las encontradas a la hora de ejecutar cualquier otra app desarrollada para macOS, y de hecho estas capacidades adicionales estarán gestionadas por el propio sistema operativo, lo que significa que no tendrás que añadir más código a tu proyecto.
Para comenzar, crearemos un Módulo en un proyecto Desktop en el cual añadiremos el método encargado de realizar esta tarea (puedes llamar al nuevo Módulo “macOSExtra”). La signatura del método añadido al nuevo módulo será la siguiente:
AddMacOSWindowMenu(item as DesktopMenuItem)
Como ves, este método espera como parámetro una instancia de DesktopMenuItem; pero antes de escribir el código de dicho método, selecciona la barra de menús añadida por omisión a tu proyecto Xojo: MainMenuBar
Al hacerlo accederás al Editor de Menús en el IDE de Xojo. Haz clic sobre el botón de la barra de herramientas encargado de añadir un nuevo elemento de primer nivel a la barra de menús:
A continuación, con el nuevo elemento añadido a la barra de menús, cambia las siguientes propiedades en el Panel Inspector asociado:
- Name: WindowMenu
- Text: Window
Selecciona a continuación el método AddMacOSWindowMenu en el Módulo “macOSExtra” y teclea el siguiente código en el Editor de Código asociado:
// El siguiente código sólo se ejecutará cuando se compile // el proyecto para macOS #if TargetMacOS then // Declaramos la función que nos permite obtener la referencia a una clase // del framework Foundation de macOS a partir del texto proporcionado // esto es, es el nombre de la clase. // Puedes encontrar más información en la documentación de Apple en: https://developer.apple.com/documentation/foundation/1395135-nsclassfromstring?language=objc Declare Function NSClassFromString Lib "Foundation" ( name As CFStringRef) As ptr var theClass As ptr = NSClassFromString("NSApplication") // Ahora que ya tenemos la referencia de la clase en cuestión // la utilizaremos para invocar al método compartido de la clase NSAplication // que nos devuelve la instancia correspondiente a la aplicación que se está ejecutando // es decir: esta aplicación sobre la que se está ejecutando este código // Puedes encontrar más información en la documentación de Apple en: https://developer.apple.com/documentation/appkit/nsapplication/shared?language=objc Declare Function GetSharedApplication Lib "AppKit" Selector "sharedApplication" (Application As ptr) As Ptr var theApp As ptr = GetSharedApplication(theClass) // Ahora que ya tenemos una referencia a la instancia de aplicación necesitamos obtener una referencia // del submenú que "cuelga" del menú de primer nivel que habremos recibido en el parámetro Item // para ello debemos invocar al Selector "submenu" del Framework AppKit, y que espera // recibir la referencia del menú principal (a la que accederemos a través de la propiedad "Handle" de // DesktopMenuItem Declare Function GetSubmenu Lib "AppKit" Selector "submenu" (menuReference As Ptr) As Ptr var subMenu As ptr = GetSubmenu( item.Handle ) // Por último asignaremos la referencia que hemos obtenido al Submenú sobre la // propiedad window de la instancia correspondiente a la aplicación // Puedes encontrar más información en la documentación de Apple en: https://developer.apple.com/documentation/appkit/nsapplication/windowsmenu?language=objc Declare Sub setWindowMenu Lib "AppKit" selector "setWindowsMenu:" ( appReference As Ptr, menuReference As Ptr) setWindowMenu( theApp, subMenu ) #EndIf
Poniéndolo a Prueba
Para ver cómo funciona este nuevo método, selecciona el ítem App en el Navegador del IDE y añade el evento Opening. A continuación, escribe la siguiente línea de código en el Editor de Código asociado:
AddMacOSWindowMenu(WindowMenu)
Ejecuta a continuación la app y haz clic sobre el ítem “Window” en la barra de menús de la app. Deberías de ver cómo el sistema operativo ha añadido una serie de opciones adicionales, similares a las siguientes (dichas opciones variarán en función de la versión de macOS sobre la que estés ejecutando la app):
Selecciona cualquiera de las opciones añadidas a dicho menú, y comprobarás que el sistema operativo responderá en consecuencia… sin necesidad de que hayas tenido que añadir código adicional para responder a las acciones en dichos manejadores de menú.
Localiza el menú Ventana
Tal y como está en este momento es probable que el menú “Window” desentone en el caso de que el resto de tu app esté localizada para otros idiomas, y cualquiera de ellos se corresponda con el definido en los ajustes de macOS > General > Idioma y Región. Para que esto no ocurra, selecciona de nuevo el módulo “macOSExtra” y añade una nueva constante “kWindowName” utilizando el valor por omisión “Window” en el Panel Inspector y activando, a continuación el switch “Localized”:
Luego utiliza el editor de constantes propiamente dicho para añadir nuevas entradas. En este caso añadiremos la localización para los idiomas Inglés y Español:
Por último, selecciona en el Navegador el elemento WindowMenu que cuelga de MainMenuBar y cambia el valor de la propiedad Text en el Panel Inspector para utilizar la nueva constante en su lugar:
Vuelve a ejecutar de nuevo la app y ahora verás que tanto el menú “Window” se muestra como “Ventana”, además de que el resto de los elementos añadidos por macOS también mostrarán la localización correspondiente al idioma establecido en General > Idioma y Región:
Conclusión
Como has visto, mediante la caracteristica de Declare disponible en Xojo es posible añadir a tus apps macOS funcionalidad adicional sin precisar de código extra; además de que tus apps tendrán un mejor aspecto cuando se ejecuten sobre dicho sistema operativo.