Trabajo de verano

Este verano estoy aprovechando para avanzar lo que me queda pendiente de programar de la tesis, que con suerte será finiquitada este año. Más que nunca veo el final, por lo que estoy contento.

En esta última instancia estoy haciendo un programa gráfico de edición de «ensamblados» de componentes. Hablaré más sobre ello, pero por ahora sólo quiero apuntar un par de cosas sobre el trabajo gráfico que estoy realizando. Escogí (ahora veo que tuve suerte y elegí bien), gtkmm, la versión C++ de GTK. Ya me había sorprendido antes por lo bien construida que estaba a partir de un sistema de objetos basado en C como es GTK, generando automáticamente la mayoría del código de Gtkmm. Además, Pango es la octava maravilla del mundo (créanme), simplificando sobremanera la tipografía de una aplicación gráfica en Gnome. Pero también hablaré más de eso. Por ahora me gustaría sólo incluir una solución a un pequeño problema que presenta esta librería y que se me ha ocurrido y me parece a la vez ingeniosa y que muestra las capacidades de C++.

La clase rectángulo (Gdk::Rectangle) tiene las funciones habituales, get _ x(), get _ y(), get _ width() y get _ height(). Para realizar dibujos y cálculos sobre áreas de la pantalla es necesario usar esta clase. El caso es que si también se utiliza Pango, uno también dispone de la clase Pango::Rectangle, con exactamente las mismas funciones de acceso y modificación.

Durante el desarrollo de la aplicación he tenido que usar ambos tipos de rectángulos, pero se me ocurrió hacer una función que desplazaba una cantidad x e y un rectángulo:


static void
displaceRect (Gdk::Rectangle& r, int x, int y)
{
r.set_x (x + r.get_x());
r.set_y (y + r.get_y());
}


Esta funciona my bien para Gdk::Rectangle, pero no para Pango::Rectangle. La solución obvia hubiera sido reescribir la función sobrecargada para el otro tipo de rectángulo y con el mismo código. Pero entonces pensé en los «templates» de C++. Es sencillo hacer un _template_ para clases que tienen el mismo interfaz (por ejemplo, porque tienen relaciones de herencia), pero también se puede hacer si las clases tienen el mismo interfaz y no están realacionadas por herencia. Así, la función quedó:


template <class Rect> void
displaceRect (Rect& r, int x, int y)
{
r.set_x (x + r.get_x());
r.set_y (y + r.get_y());
}


Que ahora vale tanto para Gdk::Rectangle como para Pango::Rectangle, y automáticamente, además. Que nadie me pregunte por qué me gusta C++ :)

blog comments powered by Disqus