]> git.llucax.com Git - z.facultad/75.42/figuras.git/blob - documentacion.h
213b8e3c5ba6ee74a288f7c7f0355b37e7bdef7a
[z.facultad/75.42/figuras.git] / documentacion.h
1 /* vim: set et ts=4 sw=4 fdm=indent tw=80 fdl=1 fdn=1 fo+=t:
2  *
3  * Taller de Programación (75.42).
4  *
5  * Ejercicio Número 5:
6  * Graficador de figuras.
7  *
8  * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9  * Puede copiar, modificar y distribuir este programa bajo los términos de
10  * la licencia GPL (http://www.gnu.org/).
11  *
12  * Creado: dom oct  5 20:39:33 ART 2003
13  *
14  * $Id$
15  */
16
17 /** \mainpage Trabajo Práctico V
18
19 \htmlonly
20 También puede ver <a href="../latex/refman.pdf">este documento en formato
21 PDF</a>.
22 \endhtmlonly
23
24 \latexonly
25 También puede ver este documento en formato HTML en html/index.html.
26 \endlatexonly
27
28 \section objetivo Objetivos.
29     - Que el alumno tome contacto con las capas de API gráficas,
30       adquiriendo la capacidad de generar gráficos simples de figuras
31       geométricas.
32     - Entender el concepto de Contexto Gráfico, y de las propiedades más
33       elementales del mismo.
34     - Manejar el concepto de Eventos, siendo el alumno capaz de armar luego
35       programas sobra la capa de API de una funcionalidad y potencia
36       considerables.
37     - Comprender el concepto de ventana y dialogo.
38     - Aplicar todos los conceptos aprendidos en la materia hasta el momento
39       de ANSI C/C++.
40
41
42 \section recursos Recursos utilizados.
43     - Herencia y Polimorfismo.
44     - ANSI C++ en general (para la codificación del programa).
45     - Funciones Callback, API <a href="http://www.gtk.org/">GDK/GTK</a>.
46
47     \note La utilización de la API <a href="http://www.gtk.org/">GDK/GTK</a>
48           para desarrollar el trabajo práctico bajo una plataforma libre
49           (GNU/Linux en este caso) fue autorizada por Andrés Veiga el día
50           30 de Septiembre de 2003.
51
52
53 \section gdk_gtk Descripción de API GDK/GTK y comparación con GDI de Windows.
54     GTK significa GIMP ToolKit ya que originalmente fue creada sólamente para
55     hacer el programa <a href="http://www.gimp.org/">GIMP</a> (GNU Image
56     Manipulation Program, una especie de Photoshop libre). Actualmente ha
57     crecido mucho, hasta superando en importancia ese proyecto inicial.
58     Creció tanto que incluso en la actualidad se compone a su vez de 2 capas
59     más, cada una siendo de más bajo nivel que la original. La capa de más bajo
60     nivel es la GLib, que implementa funciones básicas y tipos de datos comunes,
61     sirviendo de capa base para hacer aplicaciones multiplataforma. Sobre ésta,
62     está construida la biblioteca GDK (GTK+ Drawing Kit), que serviría de base
63     para hacer aplicaciones gráficas multiplataforma (aunque fuertemente
64     influída por la forma de funcionar de X Window, plataforma para la cual fue
65     creada inicialmente). GDK es entoncess de relativo bajo nivel (un nivel
66     cercano a Xlib, biblioteca de X Window, que sólo permite dibujar en pantalla
67     y manejar eventos, como el movimiento de un mouse el presionar una tecla o
68     un requerimiento para redibujar una porción de la pantalla). Sobre GDK se
69     crean una serie de \e widgets (componentes como botones, etiquetas, barras
70     de menú, etc) y a este conjunto de widgets se los llama GTK.
71     TODO
72
73
74 \section desarrollo Desarrollo.
75     El ejercicio consiste en un programa ejecutable utilizando las
76     bibliotecas <a href="http://www.gtk.org/">GDK/GTK</a> que reutilizando
77     la jerarquía de clases del Ejercicio Número 3 permita al usuario graficar
78     por pantalla ejecutando el método dibujar de la clase Dibujo. Para ello se
79     diseñó una ventana como la siguiente:
80
81     \image html  ventana.png
82     \image latex ventana.eps "Ventana Principal"
83
84     En ésta el usuario puede seleccionar el tipo de figura a dibujar, los
85     datos necesarios para dibujarla y finalmente agregarla al dibujo.
86     El programa es capaz de agregar una figura sin dibujarla y luego dibujar
87     todo al presionar el botón Actualizar.
88
89     La funcionalidad de los botones es la siguiente:
90     - \b Actualizar: Redibuja la lista interna contenida en el dibujo.
91     - \b Limpiar: Limpia el área de dibujo.
92     - \b Agregar: Inserta una nueva figura al dibujo sin graficar la misma.
93     - \b Salir: Finaliza la ejecución del programa (igual que el botón X del
94                 manejador de ventanas).
95
96     Solo puede insertarse una figura a la vez y sólo se habiliten los campos
97     correspondientes a los atributos de esa figura. Por ejemplo, si se marca
98     el \e toggle de un Rectángulo, no se puede ingresar el Radio ya que esa
99     figura no tiene dicho atributo.
100
101
102 \section resolucion Resolución.
103     \note Sólo se comentan los cambios realizados al Trabajo Práctico 3 para
104         cumplir los objetivos del actual. Por lo tanto no se hará referencia
105         a componentes como la lista interna de Dibujo y otros aspectos que ya
106         fueron evaluados en el trabajo anterior.
107
108     \subsection ventana Ventana principal.
109         Todos los componentes de la ventana principal (y la ventana en sí) se
110         encapsularon en un objeto TP5Window. Al inicializar el objeto se
111         inicializan todos los componentes de la ventana, inclusive el Dibujo que
112         contiene los objetos de tipo Figura que se van agregando. Dentro de
113         estos componentes se encuentran varios widgets GTK que se van agregando
114         a la ventana principal, guardandose un puntero como atributo de
115         TP5Window de solo aquellos widgets que se necesitarán a la hora de
116         obtener la entrada del usuario. Del resto de los widgets no es necesario
117         guardar un puntero ya que se liberan automáticamente al llamar a la
118         función gtk_main_quit().
119         TP5Window también tiene métodos para convertir o facilitar la conversión
120         de los datos que ingresa el usuario.
121         \note Para crear la ventana principal se utilizó una herramienta
122               gráfica que luego genera código automáticamente llamada Glade.
123               Sobre el código generado se cambiaron varias cosas y se
124               eliminaron llamadas a funciones inecesarias. Con este
125               programa también puede generarse un archivo XML con la disposición
126               gráfica de todos los elementos y luego cargarlo en tiempo de
127               ejecución mediante la biblioteca libglade, pero se dibujó toda la
128               interfaz con código para mostrar bien por dentro el proceso
129               realizado por dicha biblioteca.
130
131     \subsection callbacks Funciones callbacks.
132         Cada evento recibido por un widget GTK (y en general cualquier señal que
133         pueda manejar la GLib) de ser \e conectado a una función callback que se
134         encargue de menejarlo. Todas las funciones callback se agruparon en el
135         archivo callbacks.h y callbacks.cpp. Se implementaron callbacks para los
136         siguientes eventos:
137         - \c clicked:
138             Este evento se \e dispara cuando un GtkButton es presionado. Se usa
139             para borrar el dibujo, actualizarlo, agregar figuras y salir del
140             programa y es manejado por las funciones on_button_borrar_clicked(),
141             on_button_graficar_clicked(), on_button_agregar_clicked(),
142             on_button_salir_clicked().
143         - \c toggled:
144             Este evento lo \e dispara un GtkToggleButton cuando es seleccionado
145             o deseleccionado. Se usa para activar y desactivar campos para la
146             entrada de usuario al seleccionar un tipo de figura y es manejado
147             por las siguientes funciones \e callbacks:
148             on_radiobutton_linea_toggled(), on_radiobutton_cuadrado_toggled(),
149             on_radiobutton_rectangulo_toggled(),
150             on_radiobutton_circulo_toggled().
151         - \c expose_event:
152             Este Evento es \e disparado cuando se debe redibujar un área de la
153             pantalla, en este caso sólo se conecta el evento para el área de
154             dibujo para dibujar todas las figuras en la pantalla. La función que
155             maneja este evento es on_drawingarea_expose_event().
156         - \c delete_event:
157             Este evento se \e dispara cuando se solicita \e borrar una ventana.
158             Esto pasa cuando se le pide a un manejador de ventanas que \e borre
159             o \e cierre esa ventana (ya sea por la típica X en la decoración de la
160             ventana o un menú contextual, por ejemplo).
161
162         Una clara diferencia entre estos es que los dos primeros son \e internos
163         del programa, es decir, \e disparados por el mismo programa, mientras
164         que los dos últimos son eventos \e externos, generados ya sea por el
165         manejador de ventanas o por el mismo sistema gráfico (X Window o el
166         sistema operativo, dependiendo de la plataforma).
167
168     \subsection dibujando Dibujando.
169         El dibujo de las figuras comienza en la \e callback que maneja el \c
170         expose_event del área de dibujo. En ella se invoca al método
171         Dibujar::dibujar() quien a su vez llama al método Figura::dibujar() que
172         corresponda para cada dibujo en su lista interna.
173         Figura::dibujar() en sí es un método abstracto, pero hay otro método,
174         Figura::get_gc() que es utilizado por todos los métodos dibujar()
175         sobreescritos que cambia el contexto gráfico, asignando los
176         valores apropiedos al grueso y color del trazo utilizado para dibujar.
177         En cada método dibujar() sobreescrito se dibuja la figura en sí, con las
178         propiedades del contexto gráfico obtenidas de Figura::get_gc().
179
180
181 \section requerimientos Requerimientos y modo de uso.
182     \subsection plataforma Plataforma y compilador.
183         Este trabajo práctico fue realizado y probado bajo la plataforma Debian
184         GNU/Linux sid. El compilador utilizado fue GNU GCC versión 3.3.1. Se
185         utilizó la librería GTK versión 2.2.4.
186         El ejecutable entregado corre bajo esta plataforma y basta con
187         ejecutarlo para ver el resultado.
188
189     \subsection compilacion Compilación.
190         Para compilarlo basta con tener el programa \c make y los paquetes con
191         librerías para desarrollo de GTK instalados (esto incluye también
192         librerías de desarrollo de Xlib, Glib y GDK). En el caso de Debian
193         GNU/Linux sid basta con instalar los paquetes: \c make, \c xlibs-dev,
194         \c libglib2\c .0-dev, \c libgtk2\c .0-dev.
195         Teniendo estos paquetes, basta ejecutar \c make para compilar el
196         programa.
197
198
199 \section conclusiones Conclusiones.
200     Este trabajo me sirvió para profundizar sobre algunos aspectos de
201     programación de aplicaciones gráficas que no manejaba. También me sirvió
202     para saldar una cuenta que tenía hace tiempo, que era aprender sobre GTK y
203     en general Xlib (para conocer el sistema X Window a más bajo nivel) ya que
204     hasta ahora, en cuanto a aplicaciones gráficas, sólo había programado en
205     Delphi y Java, dos lenguajes (y/o API) de mucho más alto nivel.
206     Un problema con el que me encontré, a modo de anécdota, fue el manejo de
207     colores. En un principio había programado el método
208     Figura::traducir_color() pensando en mi configuración de 24 bits. Todas las
209     operaciones las realizaba operando con máscaras de bits presuponiendo 8 bits
210     por color RGB, escribiendo en pantalla \e directamente el píxel resultante.
211     Al querer probar el programa en mi trabajo, con una configuración de 16 bits
212     por píxel, por supuesto que sucedieron cosas extrañas. Fue en ese momento
213     que tuve que reescribir dicho método, utilizando las propiedades \c red,
214     \c green y \c blue de la estructura GdkColor y las funciones de la API para
215     \e preguntarle al X si el color estaba disponible y buscar un color similar
216     de no estarlo, en vez de poner directamente el color en la propiedad \c
217     pixel que almacena el valor real del píxel que se usara para poner en la
218     memoria de video.
219
220 */