sábado, 30 de julio de 2011

Anexo I: Explicación de Soplo de controles

Soplo y maikl
Tu creas una clase nueva.
Si te basas en una clase ya existente pones el inherits
Luego añades la claúsula export.
Luego tienes que definir la constante _properties que es obligatoria. Esta constante proporciona información al IDE de como debe operar con esa propiedad.
También tienes que definir un icono para ese control en la caja de herramientas.
Y por último te tienes que poner a escribir código para esas propiedades y métodos.

la constante _properties
Luego pones la variable _properties que tiene el siguiente formato:
Código: [Descargar] [Ocultar] [Seleccionar]
PUBLIC CONST _properties="*, propiedad1, propiedad2, ..., etc"

cada propiedad en la línea anterior lleva la siguiente información:
Código: [Descargar] [Ocultar] [Seleccionar]
[-] Name [ { Kind [ Arguments ] } ] = Default

El signo menos: Si una de las propiedades la declaras con un signo - significa que las quitas. Eso ocurre si usas un * para heredar todas las propiedades del padre, pero alguna de ellas no la quieres. Entonces la declaras como una mas pero con un signo menos.
La clase puede valer lo siguiente:
Color ---> un entero que representa a un color. Al verlo el IDE sacará un colorchooser para elegir el color
Font ---> Una fuente. El IDE sacará un fontchooser para elegir una fuente.
Path ---> Un path. El IDE sacará un filechooser para elegir un path
Picture ---> Una imagen o un icono de stock. El IDE sacará un picturechooser para elegirla.
Range ---> Una propiedad con valor entero y un valor mínimo y máximo. El IDE sacará un spinbox para elegirlo.
Clase ---> En vez de los casos anteriores puedes poner el nombre de una clase que contenga una lista de constantes.

Si no especificas clase entonces se utiliza el tipo de dato de la propiedad (string, ..., etc).

Ejemplo
Código: [Descargar] [Ocultar] [Seleccionar]
PUBLIC CONST _properties="Enabled=True,Font{Font},Background{Color}=-1,Foreground{Color}=-1," &
"mode{select.*}=Single,Handle,Tag"

Esto declara las siguientes propiedades:
Una propiedad TAG que no tiene ningún valor inicial. Al no especificarle nada el IDE asumirá su valor datatype especificado posteriormente.
Una propiedad HANDLE que no tienen ningún valor inicial. Al no especificarle nada el IDE asumirá su valor datatype especificado posteriormente y que como veremos es integer.
Una propiedad ENABLED que inicialmente valdrá TRUE
Una propiedad FONT. No tiene un valor inicial y para seleccionar una fuente el IDE mostrará el fontchooser.
Una propiedad BACKGROUND que tiene valor inicial -1 (no se que color es ese) y para elegirla el IDE usará el colorchooser.
Una propiedad FOREGROUND que funciona igual que la anterior.
Una propiedad MODE cuyos valores posibles están definidos como constantes en una clase llamada 'select'. Tiene por valor por defecto 'single' que es el nombre de una de esas constantes de esa clase.

Con ello habrás definido el nombre de las diversas propiedades que tendrás. el * se utiliza para heredar todas las propiedades de la clase padre si estás basando tu nueva clase en una ha existente que tendrás que heredar de la siguiente forma:
Código: [Descargar] [Ocultar] [Seleccionar]
inherits nombre_clase

Si una de las propiedades la declaras con un signo - significa que las quitas. Eso ocurre si usas un * para heredar todas las propiedades del padre, pero alguna de ellas no la quieres. Entonces la declaras como una mas pero con un signo menos.

La constante DefaultEvent
Código: [Descargar] [Ocultar] [Seleccionar]
PUBLIC CONST _DefaultEvent AS String = "Click"

Si pones esto (no es obligatorio) entonces al estar en el IDE y hacer doble click para acceder al código te saldrá el evento click para escribir código.

La constante DefaultSize
Código: [Descargar] [Ocultar] [Seleccionar]
PUBLIC CONST _DefaultSize AS String = "36,36"

Es el tamaño del control cuando lo pones en un formulario del IDE. En este caso es 36x36.

La constante _DrawWith
Código: [Descargar] [Ocultar] [Seleccionar]
PUBLIC CONST _DrawWith AS String = "TextBox"

Cuando pongas un control de esta clase en el formulario del IDE pintará un textbox.

La constante _Arrangement
Código: [Descargar] [Ocultar] [Seleccionar]
PUBLIC CONST _Arrangement AS Integer = 2 ' Arrange.Vertical

Es el arrange que tendrán sus hijos si se trata de un contenedor. En el caso propuesto es 2. Los valores posibles son los de la clase arrange.class
Solo se usa si el control es un container.

El icono del componente
En la caja de herramientas debe aparecer un icono del control para poder seleccionarlo. Para definirlo hacemos lo siguiente:
En la raíz del directorio del proyecto creamos una carpeta llamada control que contendrá los iconos (deben ser png) y el nombre del icono debe ser el nombre de la clase.

Implementación de las propiedades
Anteriormente se explicó como declararlas para el IDE. Esto es el icono que tendrá en la caja de herramientas o la manera en que el IDE debe ofrecernos dar valores a las propiedades o el valor por defecto que tendrán.

Pero llega el momento en que hay que escribir código de lo que esas propiedades hacen. Una propiedad será de tipo string o integer o lo que sea.
Código: [Descargar] [Ocultar] [Seleccionar]
PROPERTY Enabled AS Boolean
PROPERTY READ Handle AS Integer
...

PRIVATE $bEnabled AS Boolean
PRIVATE $iHandle AS Integer

' Implements the Enabled property
FUNCTION Enabled_Read() AS Boolean
RETURN $bEnabled
END

SUB Enabled_Write(bEnabled AS Boolean)
$bEnabled = bEnabled
UpdateEverything
END

' Implements the Handle property
FUNCTION Handle_Read() AS Integer
RETURN $iHandle
END

En este caso implementamos la propiedad ENABLED que es de tipo boolean.
Código: [Descargar] [Ocultar] [Seleccionar]
PROPERTY Enabled AS Boolean

y también definimos una propiedad handle que es de tipo entero y de solo lectura
Código: [Descargar] [Ocultar] [Seleccionar]
PROPERTY READ Handle AS Integer


Recuerdo que en _properties se escribió una propiedad enabled=true osea que el ide pondrá el valor true a una propiedad enabled que ahora definimos como boolean.
Como la propiedad ENABLED es de lectura escritura esta será la función para el caso de lectura (nota el _Read)
Código: [Descargar] [Ocultar] [Seleccionar]
FUNCTION Enabled_Read() AS Boolean
RETURN $bEnabled
END

Y esta será la función de escritura para ENABLED (nota el _write)
Código: [Descargar] [Ocultar] [Seleccionar]
SUB Enabled_Write(bEnabled AS Boolean)
$bEnabled = bEnabled
UpdateEverything
END

La variable $bEnabled es una variable privada y UpdateEverything es un método privado de esta clase.

La función handle es de solo lectura así que solo tiene función _read
Código: [Descargar] [Ocultar] [Seleccionar]
FUNCTION Handle_Read() AS Integer
RETURN $iHandle
END


Tras la codificación de las propiedades vendrían los métodos uno de los cuales será un método privado llamado UpdateEverything
Código: [Descargar] [Ocultar] [Seleccionar]
PRIVATE SUB UptadeEverything()
...
END

Y otros serán públicos y devolverán valores
Código: [Descargar] [Ocultar] [Seleccionar]
PUBLIC FUNCTION Ordenar(MiArray as string[]) as string[]
...
return MiArray
END


Así que en definitiva un componente nuevo que se base en un textbox y que admita la propiedad locked que sea boolean y por defecto false sería así:
Código: [Descargar] [Ocultar] [Seleccionar]
inherits textbox
export

PUBLIC CONST _properties="*,locked=false" 'el * hereda todas las propiedades de textbox
PUBLIC CONST _DefaultEvent AS String = "Keypress" 'el evento por defecto en el IDE es keypress
PUBLIC CONST _DrawWith AS String = "TextBox" 'se pinta como un textbox

PROPERTY Locked AS Boolean
PRIVATE FUNCTION Locked_read()
...
END
PRIVATE FUNCTION Locked_write()
...
END
y aquí comenzaría la declaración de métodos

Además crearemos un icono para la caja de herramientas, lo dejaremos en la carpeta controls, será de tipo png y tendrá por nombre el de la clase "miclase.png"

Con esto habremos conseguido un nuevo textbox que se llame como sea y que además de las propiedades del textbox tenga una propiedad nueva llamada locked que puede valer true o false y que hace lo que corresponda según locked_read al leer o locked_write al escribirla.(por ejemplo en este caso anular el keypress) cuando sea true

Se trata de agregar la información global del nuevo componente. Cuando vas a proyecto y propiedades para agregar algún nuevo componente aparece una lista que puedes elegir donde cada componente tiene una descripción y unos requerimientos.

Se trata de completar esa información. Se hace en Proyecto - Propiedades
Pestaña Provee
Por cada clase hay que especificar el tipo y el grupo.
El tipo es si es un control y que clase de control.
Los distintos tipos son:
class ----> una clase normal que no es un control
control --> un control que no es un container
virtual ---> Es una clase que puede ser puesta en el formulario y hace cosas pero no muetra nada (ej. el timer).
container ---> pues eso
multicontainer ----> un control container que contiene otros container pero solo uno visible a la vez como por ejemplo el tabstrip
form ---> solo posible en gambas 3 para especificar alguna nueva clase de formulario.

El grupo es el nombre de la pestaña de la caja de herramientas donde este contról estará incluído (containers, form, network, ..., etc).

La pestaña requiere
Aquí se anotan las dependencias de componentes de este nuevo componente. Por ejemplo quizá hemos hecho un componente que requiere gb.settings.

Hay cuatro opciones. Activar una de ellas (por ejemplo gestión gráfica de formularios) supone que requerimos los componentes básicos para la gestión gráfica de formularios sean cuales fueren.

Si por alguna razón necesitamos uno concreto (quizá porque es uno propio) podemos agregarlo un poquito mas abajo en la opción de componentes. en principio con las cuatro opciones anteriores no debiera ser necesario cuando se trata de componentes nativos de gambas.

Instalación
Basta con hacer el ejecutable y aparecerá en la lista de componentes de las propiedades de un proyecto.


No hay comentarios:

Publicar un comentario en la entrada