En la anterior entrega aprendimos a hacer una buena cantidad de cosas en nuestra aplicación de ejemplo, desde crear una nueva clase en Xojo hasta el modo en el que podemos añadir código a los eventos (respuestas a las acciones del usuario o del propio programa). Es decir, parte de las tuberías necesarias mediante las cuales podemos ensamblar posteriormente nuestras aplicaciones.

 

En esta ocasión nos centraremos en la definición de otra subclase a partir, nuevamente, de un control gráfico que está disponible de serie en el propio framework de Xojo. Se trata del ContainerControl.

 

Como puedes imaginar por su nombre, nos proporciona un modo tremendamente útil de englobar una serie de controles gráficos o de interfaz de usuario dentro de un único elemento. De este modo, aumentamos su capacidad de reutilización que es el principio básico de la programación orientada a objetos (o el ideal, al menos): hazlo una vez, úsalo siempre que lo necesites sin volver a crearlo desde cero.

 

Curiosamente, un ContainerControl no es ni una ventana (con la que comparte propiedades y eventos) ni tampoco llega a ser un control propiamente dicho. Está a medio camino entre ambos. Su uso es muy extendido cuando necesitamos crear interfaces gráficas complejas o dinámicas, o bien a la hora de crear un nuevo control de interfaz de usuario que sea una combinación de una serie de controles.

 

Desde el punto de vista de la creación de interfaces de usuario, los ContainerControl pueden utilizarse tanto en ventanas (clase Window) como en los PagePanel (paneles de múltiples páginas), un TabPanel (panel de múltiples pestañas) o bien dentro de otro ContainerControl.

 

ContainerControl: la base de nuestras herramientas

En nuestro caso utilizaremos una subclase del ContainerControl para añadir especialización en cuanto a su respuesta, teniendo en cuenta que lo utilizaremos para que sea la pieza de interfaz gráfica responsable de contener todos nuestros ‘Rotuladores’ (consulta la entrega anterior), así como el control adicional encargado de definir el grosor del rotulador y cualquier otro que deseemos añadir en el futuro, como por ejemplo una goma de borrar o una opción para limpiar por completo el lienzo.

 

Si seguiste la anterior entrega, ya deberías de saber cuáles son los pasos necesarios para crear una nueva clase; tan sencillo como seleccionar Insert > Class en la barra de menús. A continuación, después de asegurarnos de seleccionar la recién creada clase en el área del Navegador de Proyecto, seleccionamos el Panel Inspector y completamos las propiedades para definirla como subclase de una ya existente:

 

Name: miContainerControl

Super: ContainerControl

 

Recuerda que el nombre introducido en el campo ‘Super’ indica la clase en la que se basará, heredando por tanto sus propiedades (estado), métodos (comportamiento) y eventos (acciones). Por tanto, ya podrías utilizar en nuestra clase ‘miContainerControl’ todo lo que puedes consultar en la documentación de Xojo sobre la clase ContainerControl.

 

Pero cuando creamos una subclase es para, entre otras cosas, añadir especialización. Y eso es lo que queremos hacer aquí. Por tanto, selecciona nuestra nueva clase ‘miContainerControl’ en el Navegador de Proyecto en el caso de que no lo esté y añade una nueva propiedad ‘elColor’ introduciendo los siguientes valores en el panel Inspector:

 

Name: elColor

Type: Color

Default: &c000000

Scope: Private

 

Esta será la propiedad donde quede almacenado el color seleccionado en cada ocasión por el usuario.

 

(El lenguaje Xojo nos proporciona la sintaxis ‘&c’ en código para definir valores de color, siendo los siguientes pares de números los valores en notación hexadecimal para cada uno de los canales RGB.)

 

A continuación también nos encargaremos de definir la propiedad donde almacenaremos el grosor del rotulador que elija el usuario de nuestra aplicación de dibujo. Añade una nueva propiedad a la clase y utiliza los siguientes valores en el panel Inspector:

 

Name: grosor

Type: integer

Default: 1

Scope: private

 

Añadiremos también una propiedad  ‘miLienzo’ introduciendo los valores mostrados a continuación en el panel Inspector. Esta será la propiedad responsable de almacenar una referencia al objeto de tipo ‘Lienzo’ (cuya clase aun no hemos definido) de modo que podamos pasarle los valores de color y grosor seleccionados en cada ocasión por el usuario del programa:

 

Name: miLienzo

Type: Lienzo

Scope: protected

 

Por último, dado que se trata de una propiedad a la que deseamos acceder desde otros elementos externos (objetos), añadiremos a nuestra clase una Propiedad Computada desde el menú Insert > Computed Property. Una vez añadido, selecciónalo e introduce los siguientes valores en el panel del Inspector:

 

Name: elLienzo

Type: Lienzo

Scope: Public

 

Ahora despliégalo para que queden visibles sus métodos ‘Get’ y ‘Set’. En el primero de ellos nos limitamos a introducir la instrucción ‘Return miLienzo’ (evidentemente, sin las comillas); mientras que en el método Set introducimos el código mostrado en la imagen:

 

elLienzoSet

 

ContainerControl: añadir comportamiento

Con las propiedades (Estado) ya definido para nuestra clase, es el momento de crear los métodos que añadan comportamiento. En concreto uno de ellos se comunicará con el Lienzo proporcionándole los nuevos valores de dibujo seleccionados por el usuario (color y grosor del rotulador), mientras que nuestro segundo método (en realidad otros dos, ya verás a continuación), será de uso interno pues tendrá como cometido actualizar las propiedades de color y grosor en nuestra clase miContainerControl.

 

Asegúrate de que esté seleccionada la clase miContainerControl en el Navegador de Proyecto y añade un nuevo método mediante el menú Insert > Method. A continuación utiliza ‘actualizaCanvas’ como nombre del método en el panel Inspector y elige ‘Protected’ en el menú desplegable de Scope, también en el Inspector. En cuanto al código que debes de introducir para el método se limita a la siguiente línea:

 

ellienzo.nuevoColorYGrosor(elColor,grosor)

 

En ella estamos invocando al método ‘nuevoColorYGrosor’ del objeto disponible en nuestra propiedad ‘elLienzo’ (ya sabes que su tipo será Lienzo, tal y como la definimos), y pasando los parámetros almacenados en nuestras propiedades ‘elColor’ y ‘grosor’. Sencillo, ¿verdad?

 

Ahora crearemos el método que utilizarán los objetos gráficos del ContainerControl para comunicarnos sus cambios de estado. En principio dichos elementos gráficos serán los objetos de tipo Rotulador que ya vimos en la pasada entrega, y una subclase basada en el control gráfico ‘Slider’, aún por definir, mediante la cual seleccionaremos el grosor con el que dibujará nuestro rotulador.

 

Sobrecarga en acción

Asegúrate nuevamente de que esté seleccionado el elemento miContainerControl en el Navegador de Proyecto y añade a continuación un nuevo método. Una vez añadido, selecciona el nuevo método e introduce en esta ocasión los siguientes valores en el panel Inspector:

 

Method Name: valueChanged

Parameters: fuente as Rotulador

Scope: Public

 

Como puedes ver, el método espera recibir como parámetro un objeto de tipo ‘Rotulador’ y al que podremos acceder utilizando el nombre de variable ‘fuente’, tal y como puedes ver en el siguiente código que debes de introducir en el Editor de Código para el método recién creado:

 

elColor = fuente.colorRotulador

actualizaCanvas

 

Vuelve a añadir un nuevo método para ‘miContainerControl’, selecciónalo e introduce a continuación los siguientes datos en su panel de Inspector:

 

Method name: valueChanged

Parameters: n as integer

Scope: Public

 

Un momento, ¿cómo puede ser que un objeto tenga dos métodos con el mismo nombre? Es lo que en la programación orientada a objetos se conoce como Sobrecarga, y donde en tiempo de ejecución se conocerá qué método con un mismo identificador (nombre) debe ser invocado en base a la diferencia en el número y tipo de parámetros definidos por cada uno.

 

Ahora que ya hemos añadido un nuevo concepto importante a nuestra mochila, es el momento de escribir el código para el nuevo método:

 

grosor = n

actualizaCanvas

 

Al igual que anterior, verás que simplemente actualizamos la propiedad e invocamos el método interno de la clase encargado de actualizar el Lienzo con los nuevos valores.

 

¡Trabajo terminado! Con tres métodos y tres propiedades, más una Propiedad Calculada, ya tenemos una versión especializada del ContainerControl y que nos servirá como plataforma para nuestra paleta.

 

Consumir y declarar eventos

En la próxima entrega nos encargaremos de definir las dos últimas clases necesarias antes de que podamos empezar a diseñar la interfaz de usuario propiamente dicha. Entiendo que puede hasta ahora puede parecer un trabajo poco agradecido… pero los conceptos vistos y aprendidos son importantes, además de que servirán para que el uso posterior de las clases aceleren aun más la creación de nuestra aplicación.

 

Tags: , ,
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.

Related Article

0 Comments

Leave a Comment

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies