Hace unos días publiqué mi primer artículo de introducción sobre Xojo en Louesfera, y desde entonces espero que hayas descargado, instalado y probado el entorno de desarrollo, porque hoy vamos a llevar a cabo nuestro primer tutorial: una herramienta de dibujo básica que nos mostrará la poca cantidad de código que necesitamos para realizar un programa bastante funcional.

 

De acuerdo, nuestro particular KidPix no llega a la suela de los zapatos a un Adobe Photoshop y ni tan siquiera a Pixelmator u otras aplicaciones de dibujo y diseño de mapa de bits, pero sí que nos servirá para ver algunos conceptos importantes y poner en práctica la construcción de una interfaz de usuario mediante los controles incluidos de serie en la aplicación… y algún otro de nuestra cosecha.

 

Crayons-general

 

El resultado de nuestro proyecto de ejemplo es el que puedes ver en la imagen. No juzgues las capacidades de Xojo por lo austera de esta interfaz gráfica y, especialmente, ¡por mis cualidades como artista! Con los tutoriales procuro mantener al mínimo todo tipo de elementos innecesarios más allá de lo que se pretende explicar en cada caso, pues de lo contrario resultaría bastante más laborioso para cualquiera el poder seguir con éxito todo el desarrollo.

 

Mano a la obra. Abre Xojo y crea un nuevo proyecto de tipo Desktop. Utiliza como nombre de proyecto el que desees, ya que no tendrá incidencia sobre el desarrollo del tutorial.

 

Los elementos: cuestión de clases

Como en cualquier aplicación de dibujo, nuestra interfaz de usuario precisa de algunos elementos comunes en la interfaz de usuario: el canvas o lienzo sobre el cual dibujar, y que tendrá un tamaño fijo en cuanto a su resolución, así como los controles que nos permitirán seleccionar el color utilizado en cada momento junto con el grosor del pincel.

 

Para cada uno de estos elementos crearemos nuestras propias subclases a partir de las que ya incluye de serie Xojo.

 

Ten en cuenta que una Clase es un componente reutilizable que proporciona una funcionalidad concreta a través de sus propiedades y la invocación de sus métodos y/o eventos; es decir, las acciones que realiza y los “disparadores” a los que responde, como puedan ser por ejemplo un clic de ratón o la pulsación de una tecla.

 

Así, cuando creamos una subclase a partir de una clase ya existente lo que buscamos es personalizarla añadiendo nuevas propiedades y/o métodos para adecuarla a una función específica. Obviamente, las subclases continuarán siendo elementos reutilizables que, una vez definidas, podremos utilizar una y otra vez en nuestros proyectos.

 

Este es el primer paso de nuestro proyecto, crear las “tuberías” o piezas necesarias para componer posteriormente nuestra aplicación.

 

Crear controles de interfaz: clase Rotulador

La primera de las clases que crearemos será un control de interfaz gráfica que nos permitirá seleccionar el color con el cual dibujar sobre el lienzo. Y siempre que se trata de crear nuestros propios controles gráficos en Xojo deberemos de utilizar como punto de partida la clase Canvas que, como puedes ver en la documentación, ya cuenta de serie con una buena cantidad de funcionalidad.

 

Nuestra especialización consistirá en que deberá de incluir una imagen mediante la que pretendemos representar el color que seleccionará el usuario, además de que se producirá una reacción visual cada vez que el usuario entre con el apuntador del ratón sobre dicho control o salga de él. Obviamente, cuando el usuario haga clic sobre dicho control éste se encargará de comunicar a un control “padre” el color seleccionado.

 

subclaseCanvasInspector

 

Para añadir una nueva clase al proyecto selecciona Insert > Class en la barra de menús o bien a través del menú de herramientas. A continuación, en la ventana del Inspector introduce el texto ‘Rotulador’ en el campo ‘Name’ y ‘Canvas’ en el campo ‘Super’, tal y como se muestra en la imagen. De este modo estamos indicando que nuestra nueva clase se llamará Rotulador y que ésta heredará todas las propiedades y métodos que están disponibles para la clase sobre la que se basa, en este caso la ya mencionada Canvas.

 

Ahora es cuestión de añadir nuevas propiedades sobre nuestra clase, ya que estas serán las encargadas de contener la información de estado única que la diferencia sobre un Canvas normal: color, imagen que representará y también la referencia al controlador padre que utilizaremos para comunicar que ha sido seleccionado dicho color.

 

propiedadColorRotulador

 

En la columna del Navegador del proyecto (la situada a la izquierda de la ventana, por omisión), asegúrate de que esté seleccionada nuestra recién creada clase Rotulador. A continuación utiliza el menú Insert > Property para que se añada una nueva propiedad. Nuevamente utilizaremos el panel Inspector para declarar la nueva propiedad con el nombre ‘mColorRotulador’, el tipo de dato ‘Color’ y el ‘Scope’ o visibilidad de dicha propiedad mantenida como ‘Protected’ (protegida); de este modo nos aseguramos que ningún objeto podrá modificar directamente sus propiedades si no es mediante el uso de los métodos que hayamos designado para dicho fin.

 

propiedadImagenRotulador

 

A continuación añadiremos una nueva propiedad, en este caso se trata de la encargada de contener la imagen asociada con el color de nuestro rotulador. Asegúrate nuevamente de que esté seleccionada nuestra clase Rotulador en la columna del Navegador y repite la selección del menú para añadir una nueva propiedad. En este caso introduce para cada campo los valores: ‘Name’ -> ‘mImagen’, ‘Type’ -> ‘Picture‘ y ‘Scope’ -> ‘Protected’.

 

Repetimos nuevamente el proceso para la última de las Propiedades necesarias. En este caso utiliza los valores ‘Name’ -> ‘mContenedor’, ‘Type’ -> ‘miContainerControl’ y ‘Scope’ -> ‘Protected’. En este caso hemos utilizado para el tipo el nombre de una subclase que aun no hemos definido. No te preocupes, es algo que haremos en la siguiente entrega. Por el momento, baste saber que al igual que Rotulador es una clase de Canvas, ‘miContainerControl’ será una subclase derivada de la clase ContainerControl incluida de serie en el framework de Xojo.

 

propiedadContainerRotulador

 

Por así decirlo, los ContainerControl son un control gráfico que facilitan la reutilización de un conjunto de elementos de interfaz de usuario, ya sea dentro de una misma aplicación o en otros proyectos. En definitiva lograr un mayor desacople.

 

Métodos, añadir comportamiento

En las clase, las Propiedades son variables sobre las que se almacena el estado de un objeto; pero, ¿cómo cambiar dicho estado, más aun cuando nos hemos ocupado de que no se pueda acceder directamente a dichas propiedades al declararlas como ‘Protected’? En Xojo el sistema más recomendable de hacerlo es mediante lo que en el lenguaje se denomina Propiedad Computada (Computed Property) y que es el equivalente de lo que en otros lenguajes de programación se denominan ‘Setter’ y ‘Getter’.

 

Por tanto, para modificar nuestras tres propiedades añadiremos otras tantas propiedades computadas, siempre siguiendo la misma mecánica; y de paso ¡escribiremos nuestras primeras líneas de código!

 

Para añadir una propiedad computada, asegúrate de que esté seleccionada la clase Rotulador en la columna de Navegador de Proyecto y, a continuación selecciona en el menú Insert > Computed Property. Como de costumbre, lo primero es acudir al panel Inspector para declarar sus atributos; en este caso asignando los valores ‘Name’ -> colorRotulador, ‘Type’ -> ‘Color’ y ‘Scope’ -> ‘Public’.

 

Observa que en este caso definimos el tipo de visibilidad como ‘Public’ (Público) porque sí deseamos que otros objetos puedan acceder a las propiedades computadas de nuestra clase (en concreto a sus métodos).

 

PropiedadComputadaColorRotulador

 

Lo más interesante en este caso es que cuando se crea una Propiedad Computada observarás que se incluyen dos entradas bajo ella: Get y Set. El primero es un método que hace las funciones de respuesta; es decir, cualquier código que interrogue a un objeto basado en nuestra clase sobre dicha propiedad estará accediendo a este método. El código que incluyamos en él será el encargado de devolver el valor en cuestión. El segundo de los métodos, Set, es por el contrario el que encargado de asignar un valor a la propiedad en cuestión.

 

PropiedadComputadaColorRotuladorGetter

 

Llevando lo anterior a la práctica, selecciona la entrada ‘Get’ del elemento recién creado coloRotulador, y veremos que el área principal del IDE nos muestra el Editor de código. La única línea que hemos de introducir es la devolución de la propiedad de color mediante la instrucción Return mColorRotulador.

 

PropiedadComputadaColorRotuladorSetter

 

A continuación, selecciona el método ‘Set’ e introduce la siguiente línea de asignación para la propiedad de color: mColorRotulador = value. Observa que por omisión el método ‘Set’ utiliza en su signatura la variable ‘Value’ con el mismo tipo que el declarado (Color). Es en dicha variable donde se recibe el valor que hemos de asignar a nuestra propiedad, acción que realizamos mediante la línea de código en cuestión.

 

Repite la misma acción para crear otras dos Propiedades Computadas con los siguientes valores:

 

‘Name’ -> ‘Contenedor’

‘Type’ -> ‘miContainerControl’

‘Scope’ -> ‘Public’

 

‘Name’ -> ‘Imagen’

‘Type’ -> ‘Picture’

‘Scope’ -> ‘Public’

 

Sobre el código que has de introducir en cada uno de los pares ‘Set’ y ‘Get’ de cada propiedad computada, no deberías de tener problemas siguiendo el ejemplo de la primera que hemos creado.

 

Añadir Eventos: La respuesta de los objetos

Con lo anterior hemos terminado con la parte quizá más tediosa en la creación de nuevas clases: definir el estado (Propiedades) y las vías que permitan modificar dicho estado (Propiedades Computadas). Pero hemos dicho que se trata de una clase que derivará en un objeto de interfaz gráfica y, por tanto, debería de reaccionar ante eventos típicos como la entrada o salida del cursor del ratón del área del control o bien la realización de un ‘Clic’ (pulsación del botón) por parte del usuario. ¿Cómo llevarlo a cabo?

 

Se dice que Xojo es un lenguaje de programación orientado a objetos, al igual que ocurre con otros lenguajes como puedan ser Java, C++ u Objective-C y Python entre otros. Pero Xojo también es un lenguaje de programación orientado a eventos, es decir, con código que se ejecuta cuando se detectan los “disparadores” asignados, ya sean estos en respuesta a la interacción por parte del usuario o bien de otra índole (por ejemplo, cuando se agota un intervalo de tiempo en el caso de los temporizadores).

 

Para añadir dicho tipo de respuestas en Xojo añadimos sobre las clases lo que se denominan Manejadores de Eventos (Event Handlers), y es en dichos manejadores de eventos donde posteriormente incluiremos el código que ha de ejecutarse como respuesta.

 

Como dijimos anteriormente, queremos que nuestra clase Rotulador cree un movimiento en la posición de la imagen asignada como respuesta a que el cursor del ratón entre y salga del área que ocupe el control gráfico en pantalla. Para ello añadiremos dos manejadores de evento capaces de detectar y “atrapar” dichas acciones: MouseEnter y MouseExit (puedes leer la descripción en la documentación de la clase Canvas, referenciada anteriormente). Estarás de acuerdo en que los nombres de los eventos son totalmente descriptivos sobre su función.

 

InsertarEvento

 

Para añadir un nuevo evento en nuestra clase Rotulador, asegúrate de que esté seleccionada en la columna del Navegador de Proyecto y, a continuación, elige Insert > Event Handler en la barra de menús. Al hacerlo se abrirá un panel que contiene todos los posible eventos que se pueden añadir sobre la clase en cuestión (para ello utiliza información de la clase Superior que asignamos durante su creación). Desplázate por el listado hasta localizar ‘MouseDown’. Al seleccionarlo verás que Xojo proporciona una breve descripción sobre su cometido. Selecciónalo para que se añada a nuestra clase y repite de nuevo la operación para añadir tres manejadores de evento más: ‘MouseExit’, ‘MouseEnter’ y ‘Open’.

 

Una vez has añadido todos los manejadores de evento, selecciona este último (Open) de modo que se muestre el Editor de Código correspondiente, e introduce lo siguiente:

 

dim p as new picture(me.Width, me.Height,32)

p.Transparent = 1

me.Backdrop = p

me.Backdrop.Graphics.DrawPicture(mimagen,0,me.height/2)

 

El evento Open es el que se dispara cada vez que se crea el objeto en el programa y, por tanto, es el que se suele emplear para inicializar parte del estado del objeto. Esto es lo que hacemos en nuestro caso mediante el anterior fragmento de código, donde creamos un objeto de tipo imagen (Picture) con el tamaño del control en cuestión (ancho, alto y profundidad de color de 32 bits), y que posteriormente asignamos a la propiedad ‘Backdrop’ que tiene todo objeto Canvas con el objetivo de conseguir un contexto gráfico sobre el cual poder dibujar posteriormente la imagen del rotulador propiamente dicho. Observa que utilizamos para ello el nombre de la variable de propiedad que estuvimos creando previamente.

 

A continuación selecciona el manejados de evento ‘MouseEnter’, aquí escribiremos el código encargado de mover precisamente la imagen cuando el cursor del ratón entre en el área del control:

 

me.Backdrop.Graphics.ClearRect(0,0,me.Width,me.Height)

me.Backdrop.Graphics.DrawPicture(mimagen,0,0)

me.Refresh

 

Como puedes ver, una vez que sabemos que existe un contexto, gráfico gracias a que lo hemos creado en el evento Open del objeto (de lo contrario sería ‘Nil’), lo primero que hacemos es borrar la imagen, utilizando para ello el método ClearRect. Posteriormente volvemos a dibujar nuevamente la imagen de la propiedad ‘mImagen’ aunque en este caso sin utilizar un offset de desplazamiento, utilizando por tanto como coordenada de origen el par (0,0).

 

Por último, cada vez que realizamos una función de dibujo sobre el control indicaremos la necesidad de que se ‘redibuje’, operación que se lleva a cabo invocando el método ‘Refresh

 

Ahora, selecciona el manejador de evento MouseExit. Aquí es donde devolveremos de nuevo la imagen a su estado inicial cuando detectemos que el cursor del apuntador ya no se encuentra en el área del control:

 

me.Backdrop.Graphics.ClearRect(0,0,me.Width,me.Height)

me.Backdrop.Graphics.DrawPicture(mimagen,0,me.height/2)

me.Refresh

 

Observa que en este caso se utiliza el mismo offset de posicionamiento en la altura que el empleado con el manejados de evento Open.

 

Por último introduciremos el código que se ejecutará cada vez que el usuario pulse el botón del ratón cuando el cursor del apuntador esté dentro de nuestro control, MouseDown:

 

mcontenedor.valueChanged(me)

 

Como ya anticipamos al inicio del artículo, lo único que haremos será indicar al control superior que se ha hecho clic sobre el control. Para ello invocamos el método ‘valueChanged’ pasando el control propiamente dicho como parámetro.

 

Container Control: Crea una paleta de dibujo

¿Y cuál es ese control superior misterioso? En esta entrega ya lo hemos intuido en un par de ocasiones, al definir la propiedad mContenedor y al explicar someramente la clase Container Control en la que se basa. De hecho, esto será lo que llevemos a cabo en la próxima entrega: crear la subclase mContenedor, cuya responsabilidad en nuestra aplicación será la de contener todos los colores disponibles así como el control de ajuste de grosor del pincel.

 

Por Javier Rodríguez (@bloguintosh – www.bloguintosh.es)

Compartir
Javier Rodríguez (@bloguintosh) es desarrollador de aplicaciones. Puedes contactar con él para el desarrollo de aplicaciones y soluciones multiplataforma, así como consultoría y formación.

No hay comentarios

Dejar respuesta