30 de Diciembre 2004

Renovando el Kernel ( 2 parte )

Una de las diferencias que existen en programar un GUI para el API Win32
y GTK+, es que , mientras en el Win32 todo termina en una llamada a una
funcion CALLBACK , donde se despachan todos los eventos, en GTK+ la cosa
cambia radicalmente, ya que a parte de conectar manualmente los eventos
que queramos conectar, existe una callback distinta.

Eso supone un trabajo extra con respecto a otras GUIs para [x]Harbour,
puesto que a veces resulta que te viene como parametro una estructura,
y ahi esta el problema, harbour no tiene NI IDEA de como tratar una estructura
de C. ( Recordad que esto corre en los dos compiladores, NO SE HACE
USO DE EXTESIONES DEL LENGUAJE )


Hasta ahora, a parte de que no he tenido la necesidad de pasar ninguna
estructura, si no , que he codigo los miembros que mas me interesaban,
y es lo que recibia el method , por ejemplo, On_XXX( oSender, nKey, nType ).

Asi tengo 2 parametros , nKey y nType, que realmente son miembros de una
estructura de C.

Esto, si bien esta bien, le veo un problema, y es que no informa realmente
de todos y cada uno de los miembros de la estructura.

Imaginemos que vamos a controlar la señal , "key-press-event".

Si conocemos un poco de GTK+, veremos que el prototipo en C de la funcion
callback a donde saltara, pasara los siguientes parametros:


gboolean user_function (GtkWidget *widget,
GdkEventKey *event,
gpointer user_data);

Vemos como GdkEventKey, es un estructura que contiene bastante informacion.

Dicha estructura es la siguiente:

struct GdkEventKey {

GdkEventType type;
GdkWindow *window;
gint8 send_event;
guint32 time;
guint state;
guint keyval;
gint length;
gchar *string;
guint16 hardware_keycode;
guint8 group;
};

Ojo , todo esto esta explicado perfectamente en la documentacion disponible de GTK+ y hay
miles de ejemplos, molestaros en buscar si quereis saber mas. ;-)

Bien, en la clase gEntry, aprovecho para conectar dicha señal, para poder controlar el
objeto oGet que la clase gEntry incorpora.

No se, es que el PICTURE de los GETS que tiene xBase, dificilmente lo pueden superar
en otros lenguajes, no entiendo por que narizes tienen un Edit, EditMask, etc..., uno
para cada cosa.

Ahora , lo que viene al method OnKey_press_event() va a ser un array simulando la
estructura que le corresponderia, o lo mas compatible posible.
Asi, tendremos:

METHOD OnKey_press_event( oSender, aEventKey ) CLASS XXXX

aEventKey[ 1 ] --> Miembro type de la struct GdkEventKey
aEventKey[ 2 ] --> Miembro window " " "
aEventKey[ X ] --> Miembro XXX " " "

Generalmente, la mayoria de los miembros a mi no me dicen nada, pero , como siempre,
algun dia a alguien le puede servir, y entonces, empezamos OTRA VEZ a retocar,
y es lo que quiero evitar.

De momento lo estoy reprogramando para la POO, tambien lo hare extensible al uso de
las funciones.

A parte de esto, el programar de esta manera, de saltar directamente a los methods de las
clases, requiere prestar mucha atencion al ErrorSys, el cual he retocado ya unas cuantas
veces, y las que le quedan, porque una salida con el comando QUIT, puede llegar a ser
peor el remedio que la enfermedad.

Como Gtk+ funciona distintos al WINAPI en algunos aspectos, sobretodo cuando puedes
entrar en otro bucle de procesos de eventos, independiente de otra ventana, es necesario
ir saliendo de cada uno que tengas, ir "matando" todas las ventanas y dialogos que
tengas, etc..., cosa que en el WINAPI, seria trivial, aqui la cosa es bastante mas
complicada.

AH!! Si tuviera un array aWindows, eso seria trivial , aWindows[x]:End() ;-),
pero no dispongo de el, y no quiero disponer de el ;-)

De momento, mirare como implementar el saber lo que tengo en memoria en Harbour,
y como liberarlo.

Asi que tengo varios frentes abiertos, que para uno puede parecer complicado, pero
creo acertado terminar con los cimientos, para que el resto de los mortales pueden
terminar de edificar.

Asi, ejemplos que tenia, los he tenido que ir retocando, pues al cambiar cosas
internas, hasta el prepo, pues era totalmente imcompatibles, como por ejemplo,
estoy implementando que TODOS los widgets , los que sea logico, sean manejados a traves
del bSetGet(), de esta manera, el cambio producido en un widget, tendremos una variable
actualizada automaticamente con el valor que le corresponde.

Saludos.

Escrito por Rafa Carmona a las 1:59 PM | Comentarios (1)

16 de Diciembre 2004

Un paso mas adelante con T-Gtk...

Si bien he terminado por fin de poner en marchar el sistema nuevo de eventos,
he continuado con el tema de las clases, implementando varias mas de ellas.

Ahora tendremos, en un dia de estos volvere a liberar otra release, espero que al final de año :


+ gExpander ( Contenedor de widgets )
+ gRange -> gScaleVH ( seria como los sliders de Fw )
+ gPaned -> ( seria como los Splitters de Fw )
+ gDlgFont ( Dialogo de Seleccion de Fonts )
+ gDlgFile ( Dialogo de Seleccion de Archivos )

Para soportar el incrustar un widget a un paned, se a modificado TODAS las clases,
para permitir que se metan en el paned.

Para ello, he añadido 3 clausulas nuevas a los comandos:


+ SECOND_PANED
+ RESIZE
+ SHRINK

La explicacion esta fuera de lugar, puedes ver la ayuda de GTK+,
referente a los paneles, ahi te lo explican.

Espero un dia de estos explicar la implementación llevada a cabo en las clases
gDlgFont y gDlgFile , y como logramos gestionar los eventos del sistema y como
conectamos la señal del boton del dialogo, para que salte a nuestra clase a un
method que nosostros le digamos, recibiendo oSender, que nos servira para
obtener el nombre del fichero y/o fonts que hemos seleccionado y lo mas
importante , todo ello al nivel de PRG.

Por lo tanto, la funcion ChooseFile( )

// Devuelve fichero seleccionado...s
// cTitle := Titulo del dialogo
// cFileDefault := Directorio o fichero por defecto.
Function ChooseFile( cTitle, cFileDefault )
Local oFile := gDlgFile():New( cTitle , cFileDefault )
RETURN oFile:cFileName

Asi, entendereis la verdadera potencia que encierra recibir y saltar directamente a un method de una clase.

Saludos.

Escrito por Rafa Carmona a las 11:10 PM | Comentarios (6)

14 de Diciembre 2004

Pequelin. Una distro para los mas peques.

Mi hija se va haciendo cada vez mas grande , 3 añitos ;-), y casi siempre busco cosas por Internet para ella, para que los dos podamos disfrutar con el ordenador, no siempre va ser jugar con los little people ;-)

Buscando software, me encontre una grata sorpresa!!!
TENGO UNA METADISTRO DE GNU/LINUX PARA ELLO!!!

Lo mas interesante es que es un LIVE-CD, asi evitamos que la nena me
acabe destrozando el contenido ;-)

Por que mira que bajo Fedora intento por todos los medios que no acceda a
donde no deberia pero....SIEMPRE acaba donde no deberia , jajajaa.

Te bajas el ISO, lo quemas, y lo arrancas.
Tiene varios menus 'Inicio' para +3 Años, Primaria y Secundaria , asi como
para nivel del 'profesor'.

Me a gustado mucho el Tux-Paint, sobre todo porque mezcla sonidos con
facilidad. Cogete el gallo, jajja, menudo susto ;-)

Tambien puedes 'pegar' sus ositos de peluche, patito, etc.. por el escritorio, para
que esta mas a gusto ;-)

Vamos , por la media que he pasado, he disfrutado como un niño ;-), espero
disfrutar con mi niña, que eso de darle al raton le va cosa mala , jejeje

Otra grata sorpresa, es que esta el celestia!!! Tios, si pensais que sois
el dueño del universo, daros una vuelta por este programa, y os dareis cuenta
de lo insignificantes que somos 'ahi fuera'.

Pero eso no implica que el sistema no este acorde.
Es una DEBIAN, con Xine, acceso a Internet, Mozilla, etc... y tu xTerm.

Lo dicho, yo cada dia estoy mas convencido de que GNU/Linux esta aqui para
quedarse, y cada dia estoy mas contento de perder el tiempo en aprender sobre
el.

Si quieren mas informacion:
http://www.pequelin.org

Y todo en castellano.

Escrito por Rafa Carmona a las 9:48 PM | Comentarios (2)

7 de Diciembre 2004

Renovando el Kernel de T-Gtk

Yo pensaba que , como ya iba, para que tocarlo....pero...., creo que los beneficios
saltan tan a la vista, que no me he podido resistir a ello....

T-Gtk , se aproxima al nivel de otras Guis muy profesionales, como Xailer,
en que 'abandona' el uso del famoso array 'aControls' a la 'Fivewin', es decir,
el salto desde que se produce desde el evento del sistema a la ejecucion de
nuestro codigo.

Podemos observar en la practica totalidad de Guis bajo Harbour, de las que
disponemos el codigo, como la implementacion se basa en recorrer un array.

Explicare esta técnica, hasta ahora usado por T-Gtk+.
Aunque como siempre he dicho, por cada desarrollador y Guis existente, habra
una tecnica distinta, puesto que el programar es un arte ;-)

¿ Que es lo que pasa desde el Evento del Sistema a la ejecucion de nuestro
codigo ?

Veamos por encima el esquema :

1-EVENTO DEL SISTEMA
2-SALTO DESDE LA CALLBACK A HARBOUR
3-RECORRIDO EN BUSCA DEL HWND Y SALTO AL METHOD
4-EJECUCION DE NUESTRO CODIGO.

Explicaremos ahora los pasos que se realiza hasta llegar a nuestra ejecucion
del codigo

EVENTO DEL SISTEMA
Cuando el usuario pulsa un boton, el sistema lanza un evento, donde Gtk+,
manda la señal "clicked", en GUIs basados puramente en el API Win32, reciben
el mensaje WM_XXXX correspondiente, a continuacion....

FUNCIONES CALLBACK A HARBOUR.
Cada vez que se produce un evento, las funciones callback que hemos conectado
seran las encargadas de saltar a Harbour y es aqui donde hay una implementa-
cion por cada GUI disponible para harbour.

¿ Y porque ocurre esto ? Cada programador quiere/tiene su propia
implementacion, por diversos motivos, por su nivel o capacidad de
programacion, etc... y aqui es DONDE vemos una diferencia sustancial entre
los distintos GUIS...


RECORRIDO EN BUSCA DEL HWND Y SALTO AL METHOD
Hasta ahora, usaba un array aControls, y saltaba desde la funcion callback
a una function en Harbour llamada Entry_Point() que recibia el puntero,
y el tipo de evento producido, asi como otros parametros.
Aqui teneis la funcion :

FUNCTION ENTRY_POINT( pWidget, cEvento, nKey, nType )
LOCAL nWidget := AScan( aControls, { | oControl | oControl:pWidget == pWidget } )
Local uReturn := .F.

IF nWidget != 0
uReturn := aControls[ nWidget ]:HandleEvent( cEvento, nKey, nType )
ENDIF

RETURN uReturn

Depues de buscar en el indice , se saltaba al HandleEvent() del objeto
correspondiente y se acabo.

Si bien este sistema esta bien, tiene una pega, es que si destruimos un
objeto en cuestion, debemos de quitar su referencia en dicho array, perdiendo
ademas mas tiempo entre eventos que se pueden producir en el sistema, porque
no vamos a dejar que vaya creciendo el array, porque si no, el sistema
se vuelve mas lento, por cada control que se cree.

Una forma que usaba T-Gtk, era, que cada vez que se destruia un control,
se quitaba su referencia en el array aControls.

IF cEvento == "destroy"
ADEL( aControls, nWidget )
ASIZE( aControls, ( Len( aControls ) - 1) )
RETURN .F.

Como podeis observar, se pierde tiempo en la creacion del control, se
pierde tiempo en la gestion del evento, y se pierde tiempo en su destruccion.
Y funciona, si funciona de maravilla, pero...

¿ Que pasaria si..., hacemos desaparecer el array aControls, y la funcion
ENTRY_POINT() ?

No creo que seais unos genios al observar que la cantidad de ciclos de reloj
que le quitamos a la CPU , asi como la gestion de la memoria es ENORME!!!

Ahora , T-Gtk+ se aproxima más a Xailer, puesto que Xailer tiene una gestion
interna MUY SOTISFICADA y ENORMEMENTE RAPIDA y por cierto COJONUDAMENTE resuelto!!

En mi intento de mejorar T-Gtk, y a unas ideas de Carlos Mora, más la ayuda
inestimable de Jose F.Gimenez, padre de Xailer, he podido implementar una
parte similar a la Xailer, es decir, 'SALTO' directamente al method
correspondiente, sin necesidad de tener ningun aControls, o algo similar.

Si antes saltaba al METHOD HANDLEEVENT y de ahi al METHOD CLICKED, a traves de la funcion Entry_Point(), por cada vez que se presiona el boton , por
ejemplo, ahora salta directamente al METHOD CLICKED, ademas , pasandole
el objeto , oSender, que a producido dicho evento.

Esquematicamente , quedaria asi, tal y como estaba T-Gtk :

ENTRY_POINT()
|--> METHOD HANDLEEVENT()
| -->METHOD CLICKED()

Ahora , simplemente, se convierte por arte de magia en:
METHOD CLICKED( oSender )

Xailer realiza esto y más, como en vez de saltar a un method , ejecute un
codeblock, que sera, logicamente el siguiente paso que voy a implementar en
T-Gtk+ ;-)

Realmente, creo, bajo mi punto de visto, que Xailer es realmente MUY BUENO,
en todos los aspectos, yo simplemente me da por mirar a bajo nivel, pero
ahi esta, teneis un AUTENTICO RAD en entornos XBASE, tan facil de usar
como el delphi.
Sinceramente, jamas crei que alguien fuese capaz de hacer algo parecido,
en el mundo xbase en el que nos movemos.

Asi, que T-Gtk+ va a ser reescrito un poco para soportar la nueva forma,
a la 'Xailer', para ir abandonando el estilo a la 'Fivewin'.

Espero que al menos os haya quedado claro un pelin las distintas formas
que hay dentro de nuestro mundo Harbour, de programar Guis.

Ojo, con ello no quiero decir ni insinuar que unas sean malas o bueas, si no,
que la implementacion es 'distinta', nada más, y que cada cual, al conocer las
distintas implementaciones, y saber como funciona el tinglado por debajo.

Saludos.

Escrito por Rafa Carmona a las 11:18 AM | Comentarios (6)

2 de Diciembre 2004

Como empezar a usar T-Gtk

Todo lo que necesitas saber para empezar con T-Gtk y no morir en el intento...

Para usuarios de Windows:

1.- Compilador de C.
Teneis que instalaros el mingw32, lo podeis pillar/coger desde
http://prdownloads.sf.net/mingw/MinGW-3.1.0-1.exe?download
o si tienes el cygwin, tambien te sirve..

2.- Bajate GTK+ ( el runtime+ devel ) y el glade desde
http://gladewin32.sourceforge.net/

Para usuarios de GNU/Linux:
Eso lo teneis en los paquetes de tu distro, instalaros
el paquete de desarrollo de gtk+, glade, gcc, etc...

Para el resto de usuarios:
Si a alguien le sobra un Mac G5 y me lo manda pa casa, creo que no
tardaria mas de media hora en hacer correr T-Gtk en MAC,
en fin , si alguien se anima, contacte conmigo por e-mai


Generalmente lo tendreis en vuestro escritorio si habeis seleccionado el tema
de programacion, al menos en Mandrake y Fedora.

Descomprimir el zip que te paso, y puedes compilar cualquier ejemplo como:

Para Windows modo consola:
c:\tgk\tests\native\mingw32-make

bajo cygwin con make directamente, tambien mingw32-make, funciona.

Bajo GNU/Linux, pues make de toda la vida

Pero , compilar , deberias compilar sin problemas.
Es mas, si te fijas, tienes un gdk.c, pues todo lo que pongas ahi, a nivel de C,
te lo compilara y lo metera en la libreria.

Idem , para /src/gclass/ pero con .prg.

En el fichero Rules.make tienes que definir la ruta del compilador,.
Tambien , bajo GNU/Linux , si quereis soporte de impresion, SUPPORT_PRINT_LINUX=yes

Y muy importante es seleccionar el tipo de compilador, HB_COMPILER = mingw32 para Windows, para GNU/Linux , aunque no es necesario, se aconseja poner el gcc, por si en el ambiente del sistema teneis declarada dicha variable.

Mirar que va a buscar las librerias donde se han generado , no las que teneis
en la /lib/ , esto es asi, para :

1.- Teneis varias librerias para los distintos sistemas.
2.- Disponeis de una copia de seguridad , por si acaso ;-)

En fin, espero que no tengais problemas para compilar bajo vuestro entorno.

Saludos.

Escrito por Rafa Carmona a las 3:00 PM | Comentarios (4)