|-----------------------------------------------------------------------------|
  [ 7a69#14 ]                                                  [ 21-10-2002 ]
 \                                                                           /
  \-------------------------------------------------------------------------/
   { 12 - Programando con GLADE y LibGlade.                         }{ Fkt }
   |-----------------------------------------------------------------------|




Hola, lo que me ha llevado a escribir este documento es que en espaol hay m
cha teora sobre el tema pero he visto pocos ejemplos explicado en nuestro
idioma, por no decir ninguno, con lo cual me centrar mas en la parte prcti-
ca que en la teora.

1. Requerimientos
2. GLADE
  2.1 Qu es?
  2.2 Haciendo Una Interfaz Grfica
  2.3 Modificando Una Interfaz Grfica Ya Existente
3. LibGlade
  3.1 Introduccin
  3.2 Dando forma
  3.3 Como Compilar Nuestro Programa
  3.4 Soportes
     3.4.1 GNOME
  3.5 Recuperando Widgets
  3.6 Definiendo y Manejando Signals
4. Ejemplos De Widgets GTK+ 1.2
  4.1 GtkLabel
  4.2 GtkButton
  4.3 GtkToggleButton
  4.4 GtkEntry
  4.5 GtkSpinButton
  4.6 GtkCombo
  4.7 GtkText
5. Ejemplos Widgets De GNOME
  5.1 GnomeAppBar
  5.2 GnomeDateEdit
6. Conclusin
7. Bibliografa

Bueno pues empecemos...

1. Requerimientos

Doy por hecho que el lector tiene, por lo menos, conocimientos bsicos de C.
Para seguir el documento se necesitar una maquina con X-Windows donde correr
GLADE obviamente y si se quiere probar los Widgets de GNOME pues tener GNOME.

2. GLADE

2.1 Qu Es?

Bueno como dije antes no me extender en la parte terica asi que lo explica-
r a mi manera sin caer en definiciones tcnicas. GLADE es un IDE para crear
el interfaz grfico de una aplicacin fcilmente usando GTK y asi permitir al
programador que se centre en lo que es realmente el _core_ del programa. Lo
que quiere decir que con unos pocos de clicks nuestro programa de consola
tendr una bonito aspecto en las X-Windows ;)

2.2 Haciendo una Interfaz Grfica

Ahora ejecutamos glade desde un terminal y vemos que nos salen 3 ventanas: la
de Propiedades (Properties), la Paleta de Widgets (Palette) y la Principal
donde podremos guardar nuestro proyecto y dems.
Paso a explicar la parte que he definido como Principal: en el men File creo
que estn todas las opciones claras excepto la de Build Source Code y la de
Project Options, con lo que solo explicar esas dos; la opcin de Build Sour-
ce code no la usaremos porque aparte de que el cdigo que genera el GLADE es
dificil de manejar, por lo que tengo entendido en GLADE 2 esta opcin se qui-
tar; pinchamos en Project Options y en la pestaa General vemos que le pode-
mos cambiar el nombre la proyecto, cambiarlo de carpeta, etc... Lo de langua-
ge nos da igual porque no vamos a usar la opcin de Build Source Code. Si
queremos soporte GNOME pues marcariamos la casilla de Enable Gnome Support
pero como eso lo vamos a hacer luego a mano pues esa opcin tambin es indi-
ferente como la pongais. Las otras 2 opciones tampoco las usaremos porque co-
mo ya he dicho varias veces no vamos a usar el Build Source Code.
Bueno la ventana de Propiedades varia segn el widget que estemos usando y en
la Paleta pues estn los widgets que tendremos a nuestra disposicin. Otra
vetana que nos puede ser bastante til es la de Show Widget Tree que la po-
dremos activar dandole a View, Show Widget Tree y nos muestra en estructura
de rbol la jerarquia de los Widgets.
Una vez puesto a punto el entorno donde trabajaremos ya podemos hacer nuestra
primera aplicacin grfica para ello en la Paleta pincharemos en GTK+ Basic y
pincharemos el Widget Window, ahora si colocaramos otro Windget en la vetana
que acabamos de crear ocupara toda la ventana, sto es porque en GLADE hay
que ir poniendo Containers y ahi meter los Widgets. Pues nada eso vamos a ha-
cer asi que como nuestro fin es hacer una aplicacin que abra un simple so-
cket a un host y a un puerto determinado pues pinchamos en el container Ver-
tical Box que divide la pantalla verticalmente, cuando pinchamos nos sale un
cuadro de dilogo que nos pide cuantas filas (rows) queremos poner, le deci-
mos que 3, en la de arriba pondremos una toolbar con 2 botones asi que pin-
chamos en el widget toolbar, pinchamos en la divisin de arriba y cuando nos
pida el nmero de botones le decimos que 2. Ahora pondremos los botones a la
toolbar, para ello pinchamos en el widget button y a continuacin en el lugar
de la toolbar donde lo queramos poner, buag! pero que icono mas feo nos ha
salido, para cambiarlo seleccionamos el botn y nos vamos a la ventana de
propiedades, en Icon le damos a la lista desplegable donde nos saldrn varios
iconos prediseados (tambin podemos nosotros disear nuestro propio icono),
pinchamos en el Close, ahora en Label pondremos "Salir", y en Name pondremos
"salir_boton" para luego identificarlo mejor al manejar las signals. Ahora ha
cemos lo mismo para aadir el otro botn, esta vez le pondremos de icono el
prediseado Help, en Label "Acerca De..." y en Name "about_boton". Ahora la
divisin del medio la dividiremos en en 2 con el container Horizontal Box,
pinchamos en Horizontal Box, luego en la divisin del medio y le decimos que
lo divida en 2 columnas, ahora con esas 2 subdivisiones haremos lo mismo y
dividiremos cada una en 2 de nuevo con el Horizontal Box. Bueno espero que no
os hayais liado demasiado ;), la aplicacin debera quedar como el <scr1.png>
Sino os te queda igual pues repasa los pasos anteriores :)
Ahora en la division del medio de ms a la izquierda pondremos un widget la-
bel para ello pinchamos en la Paleta en el widget Label y luego en la divi-
sin donde lo queremos meter, lo seleccionamos y le cambiamos el Label a
"Host" y el X Pad lo ponemos a 7 para que no nos salga muy pegado al borde.
Lo siguiente que haremos ser meter un campo de texto al lado de "Host" asi
que pinchamos en el widget Text Entry y luego en la divisin que hay al lado
del Label "Host", al Text Entry en las Propiedades, en la pestaa Place pon-
dremos de Padding 7 para que no quede pegado al siguiente widget y de Name
pondremos "host_text". Bueno ahora haremos lo mismo que con el label Host y
el Text Entry en las 2 otras divisiones solo que al Label le pondremos de
Label "Puerto" y al Text Entry de Name "puerto_text". Bueno llegado a este
punto la Aplicacin tiene que estar como <scr2.png>.
Ahora en la divisin de abajo pondremos un botn, asi que pinchamos en el
widget button y luego en la divisin de abajo, ahroa nos vamos a la ventana
de Propiedades y en Stock Button seleccionamos OK y nos saldr un botn ya
prediseado y le cambiaremos el Name a "aceptado". Ahora cambiaremos en nom-
bre de la primera vetana que creamos para ello nos vamos al Widget Tree y
seleccionamos window1 y en las Propiedades cambiamos el Tittle a "Socket". Y
ya hemos terminado nuestro interfaz grfico que nos tendra que quedar como
en <src3.png>.
Para guardarlo de le damos al icono Save de la vetana Principal del GLADE y
nos guarda un archivo project1.glade en XML que luego "engancharemos" con Lib
Glade.

2.3 Modificando Una Interfaz Grfica Ya Existente

Vaya! resulta que se nos ha olvidado poner algn widget para saber si el so-
cket ha podido conectar o no, o simplemente si se ha podido crear o no, pues
no hay problema!, abrimos con el GLADE el archivo project1.glade, hacemos do-
ble click en el window1 que sale en la ventana principal del GLADE y nos sale
nuestro proyecto tal y como lo dejamos. Lo que haremos ser aadir una divi-
sin abajo y poner una barra de status, para ello vamos al Widget Tree y bus-
camos el container vbox1 (Vertical Box 1) y lo seleccionamos, ahora vamos a
las Propiedades y en Size le ponemos un 4 e voila! ya hay una divisin mas
abajo ;), ahora en la Paleta pinchamos en Gnome ya que vamos a poner una Gno-
me Application Bar que queda mas bonita que una StatusBar de GTK Basic ;), y
luego pinchamos en la divisin que hemos hecho abajo. En las Propiedades de
la GnomeAppBar le pondremos de Name "status_bar" para identificarla mejor y
le quitamos el Progress porque no lo vamos a utilizar ya que nuestra aplica-
cin es demasiado sencilla, en los ejemplos de los widgets explicar como
usar todo de la GnomeAppBar.
Joder!! se nos ha olvidado tambin hacer una ventanita de "Acerca de..." para
cuando pinchen en el botn asi que vamos a hacerla, nos vamos a la paleta a
Gnome porque ya trae una prediseada y nos quita trabajo ;), pinchamos en el
widget Gnome About Dialog y nos sale una bonita ventana de about ;=), la se-
leccionamos y en las Propiedades, en Author pondreis vuestro nombre y en co-
mments pondremos "Mi primer programa en GTK+". Ahora si tenemos la interfaz
terminada asi que la guardamos y nos tiene que haber quedado como <scr4.png>.
Como habeis podido comprobar es sumamente fcil agregar cosas a un programa
que se ha quedado obsoleto o que simplemente queremos que haga mas cosas.

3. LibGlade

3.1 Introduccin

LibGlade nos permitir "enganchar" el XML que crea el GLADE para luego hacer
lo que queramos con l en muchos lenguajes de programacin aunque en este do-
cumento solo trataremos como se hace en C.

3.2 Dando Forma

Bueno ahora entraremos en a verdadera "chicha" de la aplicacin que estamos
creando, vamos a escribir el cdigo que nos permitir manejar nuestra aplica-
cin grfica desde C, el cdigo es el siguiente:

#include <gtk/gtk.h>
#include <glade/glade.h>

#define FICH_GLADE "project2.glade"

GladeXML *prog;

int main(int argc, char *argv[]) {

  gtk_init(&argc, &argv);
  glade_init();

  prog=glade_xml_new(FICH_GLADE, NULL);
  glade_xml_signal_autoconnect(prog);

  gtk_main();
  return 0;
}

NOTA: No voy a explicar ningn cdigo entero solo lo que hacen las funciones
      a las que hace referencia el ttulo de este documento, ya se dijo al
      principio que se requerian unos bsicos conocimientos en C.

En el #define de FICH_GLADE pondremos en archivo XML que gener el GLADE, en
mi caso project2.glade, definimos un puntero a la estructura GladeXML que
usaremos para "enganchar" el XML y luego usarla desde otros archivos del pro-
yecto para manejar los widgets (de ah que la definamos como variable global)
La funcin glade_xml_new crea un nuevo objeto GladeXML con sus correspondien-
tes widgets a partir de FICH_GLADE. glade_xml_signal_autoconnect conecta las
signals que hayamos puesto con sus correspondientes widgets. gtk_main entra
en un loop esperando a que suceda algn evento en las X-Windows como que ha-
gan click en un boton del programa.

3.3 Como Compilar Nuestro Programa

Una vez tenemos ya hecho el main.c vamos a compilarlo:
gcc -o socket main.c `libglade-config --cflags --libs`

lo que hace el comando libglade-config --cflags --libs es imprimir por panta-
lla donde estn las librerias necesarias y las librerias que tiene que linkar
para que compile el programa.
Una vez lo tenemos compilado lo ejecutamos.... y.... oohhh!! que le ha pasado
a mi programa!!! no salen los dibujitos y ademas cuando lo ejecuta me da 2
warnings:

** WARNING **: unknown widget class 'GnomeAppBar'

** WARNING **: unknown widget class 'GnomeAbout'

Bien, sto pasa porque los widgets GnomeAppBar y GnomeAbout son de Gnome y
nuestro programa no tiene soporte para Gnome. El main.c que hemos hecho ser-
vira si solo usasemos widgets de GTK+ Basic y sin usar botones e iconos pre-
definidos. Para cerra nuestro programa hacemos un Control+C en la consola
donde lo hayamos ejecutado ya que an no le hemos puesto signals para que se
cierre pinchando en un botn.

3.4 Soportes

3.4.1 GNOME

Como hemos comprobado nuestro programa necesita que le pongamos soporte para
Gnome asi que eso es lo que haremos y el cdigo quedara as:

#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gnome.h>

#define FICH_GLADE "project2.glade"
#define VERSION "0.1"

GladeXML *prog;

int main(int argc, char *argv[]) {

  gnome_init ("Socket", VERSION, argc, argv);
  glade_gnome_init();

  prog=glade_xml_new(FICH_GLADE, NULL);
  glade_xml_signal_autoconnect(prog);

  gtk_main();
  return 0;
}

Vemos que hemos aadido un #include que creo que es obvio y un #define ms pa
ra indicar la versin de nuestro programa, hemos cambiado gtk_init por
gnome_init para que en el dilogo de about nos diga el nombre de nuestro pro-
grama y la versin, y por ltimo hemos cambiado glade_init por
glade_gnome_init. Ahora lo compilamos...
gcc -o socket main.c `libglade-config --cflags --libs gnome`

Ahora ejecutamos el programa y ya si sale como nosotros queriamos pero nos
sale la ventana de "Acerca De..." al iniciar el programa, esto tenemos que
arreglarlo.
Para arreglarlo se me ocurre que para practicar algo de cdigo y tal, lo bo-
rraremos del GLADE asi que abrimos nuestro proyecto con el GLADE y en el Wid-
get Tree le damos con el botn derecho del ratn a about1 y pinchamos en Dele
lete y guardamos nuestro proyecto. Ahora haremos una funcin que genere el
dilogo de about cuando nosotros queramos:

GtkWidget* crear_about(void) {
  const gchar *authors[]={ "fkt", NULL };
  GtkWidget *about;

  about=gnome_about_new("Socket", VERSION,
                        "",
                        authors,
                        _("<fkt@funfatal.org>"),
                        NULL);

  return about;
}

Es una funcin que devuelve un widget, authors es un registro que hay que re-
llenar para luego al crear la ventana de about, gnome_about_new devuelve un
widget, Socket es el nombre del programa, VERSION la versin, authors la es-
tructura que hemos rellenado antes y lo otro mi mail.

3.5 Recuperando Widgets

Supongamos que queremos recuperar el Widget button que le llamamos salir_bo-
ton pues se hara de la siguiente manera:

GtkWidget *salir_boton;

salir_boton=glade_xml_get_widget(prog, "salir_boton");

Hemos definido un widget salir_boton donde almacenaremos lo que nos devuelva
la funcin glade_xml_get_widget que, en este caso, lo que hace es devolver el
widget que le corresponda a salir_boton en el GladeXML prog y ya podemos ha-
cer lo que queramos con l.
Como habeis podido comprobar es bastante fcil recuperar los widgets que he-
mos definido en el GLADE y jugar con ellos.

3.6 Definiendo y Manejando Signals

Todo esto esta muy bien pero... para que sirve si luego no podemos hacer que
si clickeas en un widget botn nos salga la ventana de about por ejemplo?
Bien, pues para sto estn las signals, para definirlas lo haremos en el GLA-
DE ya que luego el LibGlade con glade_xml_signal_autoconnect se encargar de
conectarlas a sus respectivos widgets. As que abrimos el GLADE con nuestro
proyecto, hacemos doble click en window1 y seleccionamos el boton de acerca
de..., nos vamos a la ventana de Propiedades a la pestaa de Signals y en el
campo Signal le damos a los puntos suspensivos para que nos salga la lista de
signals de ese widget, vemos que tenemos el signal clicked, enter, leave, pre
ssed y released, a nostros el que nos viene mejor es el clicked asi que lo
seleccionamos y le damos a aadir (add), hacemos lo mismo con el boton de Sa-
lir y con el de OK.
Ya tenemos las signals que necesitamos definidas, ahora guardamos el proyecto
y haremos un main.h donde pondremos los widgets que recuperaremos en main.c
y luego usaremos en otros .c, pero antes modificaremos el main.c para recupe-
rar los widgets que vamos a usar y ademas aadiremos una llamada a la funcin
gnome_appbar_status para poner en la barra de status "Listo." cuando ejecute-
mos el programa, con lo que el main.c quedara:

#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gnome.h>

#define FICH_GLADE "project2.glade"
#define VERSION "0.1"

GladeXML *prog;
GtkWidget *about, *salir_boton, *about_boton, *aceptado, *puerto_text,
          *host_text, *status_bar, *window1;

int main(int argc, char *argv[]) {

  gnome_init ("Socket", VERSION, argc, argv);
  glade_gnome_init();

  prog=glade_xml_new(FICH_GLADE, NULL);
  glade_xml_signal_autoconnect(prog);
  salir_boton=glade_xml_get_widget(prog, "salir_boton");
  about_boton=glade_xml_get_widget(prog, "about_boton");
  aceptado=glade_xml_get_widget(prog, "aceptado");
  puerto_text=glade_xml_get_widget(prog, "puerto_text");
  host_text=glade_xml_get_widget(prog, "host_text");
  status_bar=glade_xml_get_widget(prog, "status_bar");
  window1=glade_xml_get_widget(prog, "window1");
  about=glade_xml_get_widget(prog, "about1");
  gtk_widget_destroy(about);
  gnome_appbar_set_status(GNOME_APPBAR(status_bar),"Listo.");

  gtk_main();
  return 0;
}

GtkWidget* crear_about(void) {
  const gchar *authors[]={ "fkt", NULL };
  GtkWidget *about;

  about=gnome_about_new("Socket", VERSION,
                        "",
                        authors,
                        _("<fkt@funfatal.org>"),
                        NULL);

  return about;
}

Y el main.h ser el siguiente:

#include <gnome.h>
#include <gtk/gtk.h>
#include <glade/glade.h>

GtkWidget* crear_about(void);
GtkWidget *about, *salir_boton, *about_boton, *aceptado, *puerto_text,
          *host_text, *status_bar, *window1;

NOTA: Esto se podra haber hecho poniendo en el .h el GladeXML y luego desde
      los otros .c recuperar los widgets o tambin se podra hacer hasta sin
      tener un .h, pero creo que as esta mejor estructurado con lo cual en
      nuestro ejemplo se har as.

Ahora crearemos un fichero principal.c donde controlaremos las signals y crea
remos el socket.
Las funciones que controlarn las signals se llamarn como hemos definido en
el GLADE, por ejemplo para cuando se haga click en el boton de salir de la
ToolBar se ejecutar la siguiente funcin:

void on_salir_boton_clicked (GtkButton *button, gpointer user_data) {
  <instrucciones_a_ejecutar>;
}

Los prototipos de las signals asi como las propiedades de cada widget las po-
deis ver en las Referencias que pondr al final, aunque en los ejemplos de
widgets tratar de explicar la gran mayora (todas no porque sino este docu-
mento sera interminable ;)).

Bueno ahi va el fichero principal.c:

/* Includes para el socket y atoi() */
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdlib.h>

#include "main.h"

/* Funcin para resolver un host que me prest Ripe */
unsigned long resolv(char *name); // Thx A Ripe

/* Funcin que se encarga de conectar el socket */
unsigned int conecta(struct sockaddr_in addr);

/* Funcin que se ejecutar cuando se haga click en salir_boton */
void on_salir_boton_clicked (GtkButton *button, gpointer user_data) {
  gtk_exit(0); // Termina el programa
}

/* Funcin que se ejecutar cuando se haga click en about_boton */
void on_about_boton_clicked (GtkButton *button, gpointer user_data) {
  about=crear_about(); // Creamos el dilogo de about
  gtk_widget_show(about); // Y lo mostramos
}

/* Funcin que se ejecutar cuando se haga click en aceptado */
void on_aceptado_clicked (GtkButton *button, gpointer user_data) {
  struct sockaddr_in addr;
  unsigned int ret; // control de errores
  char tmp[1024];

  /* gtk_entry_get_text devuelve un gchar* que se corresponde con con lo */
  /* que el usuario ha escrito en el widget que se le pasa como parmetro */
  /* lo de GTK_ENTRY es para conersin de tipos y que el compilador no de */
  /* warning, lo vereis en muchas funciones                               */
  addr.sin_addr.s_addr=resolv(gtk_entry_get_text(GTK_ENTRY(host_text)));
  addr.sin_port=htons(atoi(gtk_entry_get_text(GTK_ENTRY(puerto_text))));
  addr.sin_family=AF_INET;

  if (addr.sin_addr.s_addr==INADDR_NONE) {
    ret=1;
  } else {
    ret=conecta(addr);
  }

  if (ret) {
    snprintf(tmp,1024,"NO Se Ha Podido Conectar a %s", inet_ntoa(addr.sin_addr));
    /* gnome_appbar_set_status pone el gchar *tmp en el widget status_bar */
    gnome_appbar_set_status(GNOME_APPBAR(status_bar),tmp);
  } else {
    snprintf(tmp,1024,"Se Ha Conseguido Conectar a %s", inet_ntoa(addr.sin_addr));
    gnome_appbar_set_status(GNOME_APPBAR(status_bar),tmp);
  } 
}
   
unsigned long resolv(char *name) {
  unsigned long ip;
  struct hostent *he=NULL;
  ip=INADDR_NONE;
  if (!inet_aton(name, (struct in_addr *)&ip)) {
    he=gethostbyname (name);
    if (he != NULL) memcpy (&ip, he->h_addr, sizeof (ip));
  }
  return ip;
}

unsigned int conecta(struct sockaddr_in addr) {
  int sockfd;

  if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    return 1;
    
  if (connect(sockfd,(struct sockaddr *)&addr, sizeof(struct sockaddr))==-1)
    return 1;
   
  close(sockfd);

  return 0;  
}

Bueno creo que el cdigo es bastante simple y esta bien comentado asi que no
creo que haya dudas, para compilar nuestro flamante programa haremos:

gcc `libglade-config --cflags gnome` -g -O2 -Wall -c main.c
gcc `libglade-config --cflags gnome` -g -O2 -Wall -c principal.c
gcc `libglade-config --libs --cflags gnome` -g -O2 -Wall -o socket main.o principal.o

Ha costado pero por fin tenemos nuestra primera aplicacin grfica ;)

4. Ejemplos De Widgets GTK+ 1.2

En este apartado pondr algunos ejemplos de como usar las funciones y signals
de _algunos_ widgets, porque como dije antes... si pusiese todos este documen
to se hara interminable, aun as animo a cualquier persona que tenga conoci-
mientos sobre el tema a que escriba sobre los widgets que me deje yo en el
tintero. Tampoco explicar funciones que se derivan de propiedades, por ejem-
plo para el widget Label para justificar el texto a la derecha en realidad se
hace llamando a la funcin gtk_label_set_justify pero eso se puede hacer fa-
cilmente con el GLADE en la ventana de Propiedades; ni tampoco funciones que
hace el GLADE automticamente al poner le widget como la de crearlo.

4.1 GtkLabel

-Qu es?:

Etiqueta.

-Funciones:

De aqu la nica funcin que explicar es gtk_label_get que lo que hace es po
ner en un gchar que nosotros le demos el texto del label del widget. Por ejem
plo si la propiedad label del widget tiene de contenido "OK" y el nombre (na-
me) es "label1" pues haciendo gtk_label_get(GTK_LABEL(label1), buf); tendra-
mos en buf "OK". El prototipo de esta funcin es:
void gtk_label_get(GtkLabel *label, gchar **buf);

-Propiedades:

+ justify: Justifica el texto, las macros que permiten hacer esto son:
  GTK_JUSTIFY_LEFT, GTK_JUSTIFY_RIGHT, GTK_JUSTIFY_CENTER y GTK_JUSTIFY_FILL.
  Se puede hacer facilmente desde la ventana de propiedades del GLADE.

+ label: Contiene el texto que tendr la etiqueta. Tambin se cambia facilmen
  con el GLADE.

+ pattern: Se usa mucho en los mens, es subrayar la letra que al darle har
  la misma funcin que si dieramos un click con el ratn. Es facilmente modi-
  ficable en el GLADE.

4.2 GtkButton

-Qu es?:

Botn Simple.

-Funciones:

+ gtk_button_presed:
   Prototipo
    void gtk_button_pressed(GtkButton *button);

  Esta funcin manda el signal pressed al widget button.

+ gtk_button_released:
   Prototipo
    void gtk_button_released(GtkButton *button);

  Manda el signal released al widget button.

+ gtk_button_clicked:
   Prototipo
    void gtk_button_clicked(GtkButton *button);

  Manda el signal clicked al widget button.

+ gtk_button_enter:
   Prototipo
    void gtk_button_enter(GtkButton *button);

  Manda el signal enter al widget button.

+ gtk_button_leave:
   Prototipo
    void gtk_button_leave(GtkButton *button);

  Manda el signal leave al widget button.

  Un ejemplo de estas funciones anteriores podra ser:
  gtk_button_clicked(GTK_BUTTON(boton_salida));
  Siendo GtkWidget *boton_salida; despus de ejecutar esta funcin el progra-
  ma ejecutara la funcin que hubiera asociada a este signal (si es que la
  hubiese), las dems funciones anteriores son anlogas a sta.

+ gtk_button_set_relief:
  Facilmente configurable desde GLADE, pone un estilo de relieve al botn de
  tipo GtkReliefStyle que puede ser: GTK_RELIEF_NORMAL, GTK_RELIEF_HALF o
  GTK_RELIEF_NONE.

+ gtk_button_get_relief:
   Prototipo
    GtkReliefStyle gtk_button_get_relief(GtkButton *button);

  Dice el estilo de relieve que tiene el widget button.

   Ejemplo
    estilo gtk_button_get_relief(GTK_BUTTON(boton1));
    Siendo: GtkStyleRef estilo; GtkWidget *boton1;

-Propiedades:

+ label: El texto que tendr el botn.

+ relief: Relieve del botn.

-Signals:

+ pressed:
  Cuando el botn se encuentra pulsado inicialmente.

+ released:
  Cuando el botn que estaba pulsado se "suelta".

+ clicked:
  Cuando se hace click en el botn con el ratn, si el puntero del ratn no
  est en el botn el signal no se emite.

+ enter:
  Cuando el puntero del ratn entra en el botn.

+ leave:
  Cuando el puntero del ratn sale del botn.

Para todas estas signals el prototipo es el mismo:
void funcion_predefinida_en_el_glade(GtkButton *boton, gpointer user_data);
En el ejemplo del programa que hemos hecho en este documento se ve claramente

4.3 GtkToggleButton

-Qu es?:

Botn que si lo pulsas se queda "toggled" (pulsado) hasta que lo vuelvas a
pulsar.

-Funciones:

+ gtk_toggle_button_toggled:
   Prototipo:
    void gtk_toggle_button_toggled(GtkToggleButton *boton);

  Cambia el estado del botn, si el botn estaba activado lo desactiva.

+ gtk_toggle_button_get_active:
   Prototipo:
    gboolean gtk_toggle_button_get_active(GtkToggleButton *boton);

  Nos dice si el botn esta o no activado, si est activado devuelve TRUE y
  sino devuelve FALSE.

+ gtk_toggle_button_set_active:
   Prototipo:
    void gtk_toggle_button_set_active(GtkToggleButton *boton, gboolean estado);

  Pone el botn en el estado que le digamos, activado o desactivado.

  Ejemplo:
  (Esto se suponiendo que ya se ha puesto el toggle button con el GLADE y se
   ha enganchado el XML)

  GtkWidget *bool_proxy;
  int usar_proxy=0;

  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bool_proxy))) {
    usar_proxy=1;
    gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(bool_proxy));
  }

  if (!usar_proxy) {
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bool_proxy),TRUE);
  }

-Propiedades:

+ active: Estado del botn, si esta presionado o no. Es un gboolean (TRUE o
  FALSE).

-Signals:

+ toggled:
  Cuando el estado del botn cambia, ya sea de TRUE a FALSE o viceversa.
   Prototipo:
    void funcion_predef(GtkToggleButton *boton, gpointer user_data);

4.4 GtkEntry

-Qu es?:

Es una caja de texto.

-Funciones:

+ gtk_entry_set_text:
   Prototipo:
    void gtk_entry_set_text(GtkEntry *entry, const gchar *text);

  Pone un texto en la caja reemplazando el existente (si es que lo habia).

+ gtk_entry_append_text:
   Prototipo:
    void gtk_entry_append_text(GtkEntry *entry, const gchar *text);

  Concatena el texto que habia en la caja (si es que lo habia) con el nuevo.

+ gtk_entry_prepend_text:
   Prototipo:
    void gtk_entry_prepend_text(GtkEntry *entry, const gchar *text);

  Antepone el texto nuevo al que habia (si lo hubiese).

+ gtk_entry_get_text:
   Prototipo:
    gchar* gtk_entry_get_text(GtkEntry *entry);

  Devuelve un puntero a gchar donde estar el contenido de la caja de texto.

+ gtk_entry_set_visibility:
   Prototipo:
    void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible);

  Si visible es FALSE lo que se escriba o haya en la caja aparecer con aste-
  riscos (*), y si es TRUE aparecer texto plano normal.

+ gtk_entry_set_editable:
   Prototipo:
    void gtk_entry_set_editable(GtkEntry *entry, gboolean editable);

  Determina si esa caja de texto puede ser editada o no por el usuario, si
  editable es FALSE el usuario no podr editarla.

+ gtk_entry_set_max_length:
   Prototipo:
    void gtk_entry_set_max_length(GtkEntry *entry, guint16 max);

  Pone un mximo de caractres a escribir en la caja de texto. Si el usuario
  se pasa de ese mximo los caractres se truncarn hasta el mximo definido.

NOTA: Muchas de estas funciones estn obsoletas y sern reemplazadas por fun-
      ciones del widget GtkEditable.

  Ejemplo:

  GtkWidget *pass_text, *user_text;
  gchar *pass, *user;

  gtk_entry_set_text(GTK_ENTRY(user_text),"Pon Aqu Tu Usuario");
  gtk_entry_set_visibility(GTK_ENTRY(pass_text),FALSE);
  /* Poner los caracteres visibles o no asi como ponerla editable o no */
  /* es mas sencillo hacerlo desde GLADE                               */
  gtk_entry_set_max_length(GTK_ENTRY(user_text),8);
  pass=gtk_entry_get_text(GTK_ENTRY(pass_text));
  user=gtk_entry_get_text(GTK_ENTRY(user_text));

  if (!strncmp(pass,user,8)) {
    /* g_print() es equivalente a printf(), imprime por la consola */
    g_print("Usuario Vlido\n");
  } else {
    g_print("ERROR: Usuario NO Vlido\n");
  }

-Propiedades:

+ max_length: es un guint (unsigned int) que indica el mximo de caracteres.

+ visibility: gboolean que indica si el texto saldr en asteriscos o en texto
  plano.

4.5 GtkSpinButton

-Qu es?:

Es ideal cuando queremos que el usuario meta un valor y lo pueda incrementar
en lo que nosotros queramos y tiene multiples propiedades para hacerlo ms o
menos estricto.

-Funciones:

Muchas las voy a omitir ya que es mucho mas sencillo ajustar las propiedades
con el GLADE. En la vetana de Propiedades de un SpinButton tendremos lo si-
guiente:
Climb Rate es lo que escalar para ajustarlo.
Digits sern los nmeros decimales que habr en el SpinButton.
Numeric, si ponemos esto a Yes y el usuario mete un carcter ser ignorado,
excepto el '-' y el '.'
Snap, si ponemos Snap a Yes cuando el usuario ponga un nmero que no est en
los incrementos definidos automticamente se ajustar.
Wrap, si la ponemos a Yes y el usuario se pasa de nuestro mximo, que suponga
mos que es 5 automticamente se pondr un 5, lo mismo pasara con el mnimo.
Step Inc que ser lo que subamos cada vez que el usuario pinche en la flecha
del botn para incrementar, o igualmente pero decrementando.
Las funciones ms interesantes son:
+ gtk_spin_button_get_value_as_float:
   Prototipo:
    gfloat gtk_spin_button_get_value_as_float(GtkSpinButton *spin_button);

  Almacena en un gfloat el valor que contenga el spin button.

+ gtk_spin_button_get_value_as_int:
   Prototipo:
    gint gtk_spin_button_get_value_as_int(GtkSpinButton *spin_button);

  Almacena en un entero el contenido del spin button.

  Ejemplo:

  GtkWidget *spin;
  gint num;
  gfloat nfloat;

  nfloat=gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(spin));
  num=gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(spin));
  g_print("Valor del Spin: entero-> %d - float-> %f\n", num, nfloat);

-Propiedades:

Mirar en las funciones de este widget :).

4.6 GtkCombo

-Qu es?:

Es una caja que te da a elegir entre varias opciones.

-Funciones:

Antes de nada decir que el GtkCombo se compone de un GtkEntry que contendr
la opcin que se haya seleccionado, asi que ser lo que tendremos que leer a
la hora de querer saber la opcin elegida por el usuario.
Una vez ms se puede hacer todo mucho mas sencillo con el glade sin tener que
llamar a funciones, en el GLADE seleccionamos el GtkCombo entero (no solo el
GtkEntry que tiene), y en la ventana de propiedades vemos Items ahi es donde
tendremos que meter los elementos entre los que podr elegir el usuario. Tam-
bin podemos definir si ser Case Sensitive en caso de que el usuario pueda
editar la GtkEntry.

4.7 GtkText

-Qu es?:

Es como un GtkEntry gigante :), un espacio donde se podr o no (segn desee
el programador) escribir/ver texto.

-Funciones:

Se puede poner editable o no, con el GLADE sin tener que llamar a ninguna fun
cin.

+ gtk_text_set_point:
   Prototipo:
    void gtk_text_set_point(GtkText *text, guint index);

  Pone el cursor en la posicion dada por index.

+ gtk_text_get_point:
   Prototipo:
    guint gtk_text_get_point(GtkText *text);

  Devuelve la posicin del cursor en el GtkText.

+ gtk_text_get_length:
   Prototipo:
    guint gtk_text_get_length(GtkText *text);

  Devuelve la longitud del texto completo que haya.

+ gtk_text_freeze:
   Prototipo:
    void gtk_text_freeze(GtkText *text);

  No deja que se escriba mas en el widget hasta que se llame a gtk_text_thaw,
  es til si se hacen cambios muy rpido en el widget para que el usuario vea
  el resultado.

+ gtk_text_thaw:
   Prototipo:
    void gtk_text_thaw(GtkText *text);

  Vuelve a dejar escribir en el widget despues de un freeze.

+ gtk_text_insert:
   Prototipo:
    void gtk_text_insert(GtkText *text, GdkFont *font, GdkColor *fore, 
                         GdkColor *back, const char *chars, gint length);

  Inserta un texto chars en el widget text con la fuente font etc..., fore
  es el color del texto y back el color del fondo.

+ gtk_text_backward_delete:
   Prototipo:
    gint gtk_text_backward_delete(GtkText *text, guint nchars);

  Borra un nmero de caractres, a partir de la posicin del cursor para
  atrs dado por nchars y devuelve TRUE si se ha podido realizar la operacin
  o FALSE en caso contrario.

+ gtk_text_forward_delete:
   Prototipo:
    gint gtk_text_forward_delete(GtkText *text, guint nchars);

  Hace y devuelve lo mismo que gtk_text_backward_delete pero borra los carac-
  tres a partir de la posicin del cursor para adelante.

  Ejemplo:

  GtkWidget *texto;
  GdkColor *foreground, *background;
  guint tam;

  foreground->red=0;
  foreground->blue=65535;
  foregroung->green=0;
  background->red=0;
  background->green=0;
  background->blue=0;

  gtk_text_insert(GTK_TEXT(texto),GDK_FONT_FONT,foreground, background,
                  "hola",4);

  if(gtk_text_backward_delete(GTK_TEXT(texto),2))
    g_print("Borradas 2 letras\n");

  tam=gtk_text_get_length(GTK_TEXT(texto));

  g_print("Longitud del texto actual: %d\n", tam);

5. Ejemplos Widgets De GNOME

5.1 GnomeAppBar

-Qu es?:

Es una barra de estado + una barra de progreso.

-Funciones:

Desde el GLADE se puede quitar la barra de estado o la barra de progreso, o
las 2, segn se prefiera.

+ gnome_appbar_set_status:
   Prototipo:
    void gnome_appbar_set_status(GnomeAppBar *appbar, const gchar *status);

  Pone en la barra de estado el mensaje status.

+ gnome_appbar_push:
   Prototipo:
    void gnome_appbar_push(GnomeAppBar *appbar, const gchar *status);

  Pone en la pila de mensajes de la barra de estado el mensaje status y ade-
  ms sale en la barra de estado.

+ gnome_appbar_pop:
   Prototipo:
    void gnome_appbar_push(GnomeAppBar *appbar);

  Saca de la pila el ltimo mensaje metido y pone el siguiente en la barra de
  estado.

+ gnome_appbar_clear_stack:
   Prototipo:
    void gnome_appbar_clear_stack(GnomeAppBar *appbar);

  Borra la pila de mensajes de la barra de estado y pone el default message,
  si lo hubiese, en la barra de estado. El default message se pone con la
  funcin gnome_appbar_set_default que recibe un widget appbar y un gchar.

+ gnome_appbar_set_progress:
   Prototipo:
    void gnome_appbar_set_progress(GnomeAppBar *appbar, gfloat percentage);

  Rellena la barra de progreso con el porcentaje dado en percentage en float.

  Ejemplo:

  Hay ejemplos sobre este widget en el programa que hemos hecho al principio
  del documento.

5.2 GnomeDateEdit

-Qu es?:

Es un widget en el cual el usuario puede cambiar la hora y la fecha.

-Funciones:

La mayora de las funciones de este widget son para ajustar propiedades y se
puede hacer con el GLADE mucho ms fcilmente.

+ gnome_date_edit_get_date:
   Prototipo:
    time_t gnome_date_edit_get_date(GnomeDateEdit *gde);

  Devuelve el la fecha y la hora que hay en ese momento en el widget.
  NOTA: time_t es un long int.

-Signals:

+ date_changed:
  Se produce cuando el usuario cambia la fecha.
   Prototipo:
    void funcion_predef(GnomeDateEdit *dateedit, gpointer user_data);

+ time_changed:
  Se produce cuando el usuario cambia la hora.
   Prototipo:
    void funcion_predef(GnomeDateEdit *dateedit, gpointer user_data);

6. Conclusin

Despus de este artculo (si se puede llamar asi :)) espero que seais capaces
de seguir aprendiendo a manejar los muy variados widgets que hay, y que encon
trareis en las URL del punto siguiente (la bibliografa). Espero que os haya
servido de ayuda.
Un Saludo.

7. Bibliografa

http://developer.gnome.org/doc/API/libglade/libglade.html - API LIBGLADE
http://developer.gnome.org/doc/API/gtk/index.html - API GTK+
http://developer.gnome.org/doc/API/libgnomeui/book1.html - API GNOME UI


*EOF*
