\section gdk_gtk Descripción de API GDK/GTK y comparación con GDI de Windows.
- GTK significa GIMP ToolKit ya que originalmente fue creada sólamente para
- hacer el programa <a href="http://www.gimp.org/">GIMP</a> (GNU Image
- Manipulation Program, una especie de Photoshop libre). Actualmente ha
- crecido mucho, hasta superando en importancia ese proyecto inicial.
- Creció tanto que incluso en la actualidad se compone a su vez de 2 capas
- más, cada una siendo de más bajo nivel que la original. La capa de más bajo
- nivel es la GLib, que implementa funciones básicas y tipos de datos comunes,
- sirviendo de capa base para hacer aplicaciones multiplataforma. Sobre ésta,
- está construida la biblioteca GDK (GTK+ Drawing Kit), que serviría de base
- para hacer aplicaciones gráficas multiplataforma (aunque fuertemente
- influída por la forma de funcionar de X Window, plataforma para la cual fue
- creada inicialmente). GDK es entoncess de relativo bajo nivel (un nivel
- cercano a Xlib, biblioteca de X Window, que sólo permite dibujar en pantalla
- y manejar eventos, como el movimiento de un mouse el presionar una tecla o
- un requerimiento para redibujar una porción de la pantalla). Sobre GDK se
- crean una serie de \e widgets (componentes como botones, etiquetas, barras
- de menú, etc) y a este conjunto de widgets se los llama GTK.
- TODO
+ \subsection intro Introducción y un poco de historia de GTK.
+ GTK significa GIMP ToolKit ya que originalmente fue creada sólamente para
+ hacer el programa <a href="http://www.gimp.org/">GIMP</a> (GNU Image
+ Manipulation Program, una especie de Photoshop libre). Actualmente ha
+ crecido mucho, hasta superando en importancia ese proyecto inicial.
+ Creció tanto que incluso en la actualidad se compone a su vez de 2 capas
+ más, cada una siendo de más bajo nivel que la original. La capa de más bajo
+ nivel es la GLib, que implementa funciones básicas y tipos de datos comunes,
+ sirviendo de capa base para hacer aplicaciones multiplataforma. Sobre ésta,
+ está construida la biblioteca GDK (GTK+ Drawing Kit), que serviría de base
+ para hacer aplicaciones gráficas multiplataforma (aunque fuertemente
+ influida por la forma de funcionar de X Window, plataforma para la cual fue
+ creada inicialmente). GDK es entonces de relativo bajo nivel (un nivel
+ cercano a Xlib, biblioteca de X Window, que sólo permite dibujar en pantalla
+ y manejar eventos, como el movimiento de un mouse el presionar una tecla o
+ un requerimiento para redibujar una porción de la pantalla). Sobre GDK se
+ crean una serie de \e widgets (componentes como botones, etiquetas, barras
+ de menú, etc) y a este conjunto de widgets se los llama GTK.
+
+ \subsection diferencias Diferencias con GDI de Windows.
+ A continuación daremos algunas diferencias básicas entre ambas APIs, a
+ fin de explicar como pensar en GTK sabiendo como programar con la GDI
+ de Windows.
+
+ Todo programa GTK comienza, como todo programa en C, con la función main()
+ (en lugar de WinMain() como en GDI), pues no es más que un programa común y
+ corriente que se comunica con un servidor X Window que provee el servicio
+ de dibujar gráficos en un \e Display y capturar las entradas del usuario
+ (entre alguna otra cosa). Como paso inicial se debe inicializar la API
+ llamando a la función gtk_init(). Esta función recibe como parámetros
+ los argumentos de main(), ya que en X Window es posible configurar
+ parámetros (como el Display) desde la línea de comando, además de que GTK
+ soporta parámetros para cambiar el skin con que se renderizará, entre otras
+ funciones.
+
+ Para crear la ventana y los componentes se puede utilizar la aplicación
+ Glade, que genera el código C de la creación de la ventana. A diferencia
+ del Visual C++ que utiliza archivos de recursos para la creación de la
+ ventana con interfaz RAD. Básicamente todo widget se crea como la llamada
+ a la función gtk_<nombre del widget>_new, que encapsula a la llamada de
+ la función de la XLib CreateWindow. Con Glade también es posible generar un
+ archivo XML con la descripción de la interfaz gráfica parecido al archivo de
+ recursos de Windows, con la diferencia de que este archivo se carga en
+ tiempo de ejecución y todo lo que hace es crear todos los widgets por
+ nosotros a través de las funciones antes mencionadas. Otra diferencia es que
+ el archivo de recursos de Windows se \e compila y es parte del ejecutable
+ mientras que el XML de glade queda por fuera y puede ser cambiado sin
+ recompilar.
+
+ Un punto donde la programación difiere es en el manejo de los callbacks y
+ captura de eventos. Como GTK está pensada para ser multiplataforma, se
+ propuso un nuevo sistema de eventos y nuevas denominaciones para los
+ nombres de los eventos, ya que no todos los eventos que tienen la GDI
+ existen el X Window por ejemplo. Es así que cada evento, en lugar de ser
+ una constante WM_*, se define por una cadena con el nombre del evento.
+ Además, en GTK se definen un callback por evento, en lugar de un callback
+ por ventana/widget. Esto trae la ventaja de poder separar el código de
+ manera más prolija cuando se tienen mucho eventos.
+
+ Los eventos se conectan con la función g_signal_connect, que tiene por
+ argumentos a la ventana, el nombre del evento, el callback que lo atiende y
+ un parámetro opcional para pasar datos.
+ Otra diferencia es como se identifican los objetos de una ventana. En GTK
+ cada elemento se identifica con una cadena de caracteres que define su
+ nombre, el cual debe ser único. Cuando se desea obtener el objeto para
+ tratar con el se debe buscar a través de todos los widgets hasta
+ encontrarlo. Glade ayuda creando una función lookup_widget que se encarga
+ de esta tarea, aunque también puede guardarse directamente un puntero a los
+ widgets importantes para accederlos fácilmente, independizándose así de la
+ necesidad de usar Glade para hacer la interfaz.
+ El ciclo de eventos principal de toda aplicación GTK comienza cuando es
+ ejecutada la función gtk_main(), que contiene el código con el \e loop
+ principal que se encarga de, según la plataforma, recibir y despachar los
+ mensajes a los callbacks correspondientes. El programa finaliza cuando este
+ loop finaliza, pudiendo cortar el ciclo llamando al gtk_main_quit();
+
+ \subsection no_gtk Programación en X Window sin GTK.
+ Existen también otros toolkit, como X Toolkit y Motif Toolkit. Estas API
+ están un paso más arriba que la XLib, pero varios más abajo que la GTK
+ (aunque sigue varios pasos más arriba que la GDK), haciendo casi tan
+ tediosa la programación como si se trabajara directamente sobre la XLib.
+ La creación de todo widget en Motif requiere de al menos 5 o 6 parámetros.
+ No existe aplicación RAD para facilitar la creación de la ventana y el
+ manejo de los callbacks no es trivial.
+ Por estas razones se eligió GTK, ya que es lo mas parecido a la API Win32
+ en complejidad.
\section desarrollo Desarrollo.
inicializan todos los componentes de la ventana, inclusive el Dibujo que
contiene los objetos de tipo Figura que se van agregando. Dentro de
estos componentes se encuentran varios widgets GTK que se van agregando
- a la ventana principal, guardandose un puntero como atributo de
+ a la ventana principal, guardándose un puntero como atributo de
TP5Window de solo aquellos widgets que se necesitarán a la hora de
obtener la entrada del usuario. Del resto de los widgets no es necesario
guardar un puntero ya que se liberan automáticamente al llamar a la
\note Para crear la ventana principal se utilizó una herramienta
gráfica que luego genera código automáticamente llamada Glade.
Sobre el código generado se cambiaron varias cosas y se
- eliminaron llamadas a funciones inecesarias. Con este
+ eliminaron llamadas a funciones innecesarias. Con este
programa también puede generarse un archivo XML con la disposición
gráfica de todos los elementos y luego cargarlo en tiempo de
ejecución mediante la biblioteca libglade, pero se dibujó toda la
interfaz con código para mostrar bien por dentro el proceso
realizado por dicha biblioteca.
- \subsection callbacks Funciones callbacks.
+ \subsection callbacks Funciones \e callback.
Cada evento recibido por un widget GTK (y en general cualquier señal que
pueda manejar la GLib) de ser \e conectado a una función callback que se
- encargue de menejarlo. Todas las funciones callback se agruparon en el
+ encargue de manejarlo. Todas las funciones callback se agruparon en el
archivo callbacks.h y callbacks.cpp. Se implementaron callbacks para los
siguientes eventos:
- \c clicked:
\subsection dibujando Dibujando.
El dibujo de las figuras comienza en la \e callback que maneja el \c
expose_event del área de dibujo. En ella se invoca al método
- Dibujar::dibujar() quien a su vez llama al método Figura::dibujar() que
+ Dibujo::dibujar() quien a su vez llama al método Figura::dibujar() que
corresponda para cada dibujo en su lista interna.
Figura::dibujar() en sí es un método abstracto, pero hay otro método,
Figura::get_gc() que es utilizado por todos los métodos dibujar()
sobreescritos que cambia el contexto gráfico, asignando los
- valores apropiedos al grueso y color del trazo utilizado para dibujar.
+ valores apropiados al grueso y color del trazo utilizado para dibujar.
En cada método dibujar() sobreescrito se dibuja la figura en sí, con las
propiedades del contexto gráfico obtenidas de Figura::get_gc().