Wednesday, October 28, 2009

Widgets personalizados en la barra de tareas

Como ya sabéis (o deberíais) Twinpanel usa una encapsulación del ActionGroup de GTK (menu.ActionManager) dónde se pueden añadir de forma muy parecida a cómo se hace en GTK acciones que se mostrarán, dependiendo de la "location" especificada, en la barra de menú o en la de herramientas.

El problema de esto es que GTK solo proporciona algunos tipos de acciones (gtk.Action y algunos más) que generan elementos en el menú de herramientas, lo que hace imposible en principio añadir un widget genérico en dicha barra.

Para poder hacer esto se debe crear una especialización de gtk.Action (de forma que el ActionGroup de GTK pueda aceptarlo como acción), registrarlo en la factoría de tipos de GObject y, tras ello, decirle que tipo de widget debe representar. El widget a su vez debe ser una especialización de gtk.ToolItem.

¿Lioso? Bueno, no tanto. Como nosotros queremos añadir un widget personalizado tan solo deberíamos crear una especialización del gtk.ToolItem y, al ser estos también especialización de gtk.Container, añadir nuestro widget en ellos (y, por supuesto, no os olvidéis de hacer el "show" de nuestro widget).

Con esto he creado un pequeño ejemplo que se puede ver en el fichero widget.py de la distribución "stable"de Twinpanel.

Tenemos una clase "SpinAction", que hereda de gtk.Action y está registrada en la factoría de Gobject. La especialización de ToolItem en este caso es "SpinToolButton", que en su constructor crea un SpinButton y se lo añade y muestra. Además tiene una serie de métodos, propios de SpinButton, que nos permite acceder y modificar su valor, además de los callbacks que se conectan con los de SpinButton para emitir nuestras propias señales (que por supuesto están registradas en gobject unas líneas más abajo).

Con esto simplemente tendremos que crear una instancia de SpinAction y añadirla a nuestro ActionManager con "add_real_action" (TODO: debe cambiarse dicho nombre para que sea "add_action", y cambiar el actual "add_action" a algo más apropiado).

Lo mismo que con el ejemplo que acabo de explicar estoy intentando hacer con el MenuToolButton, para que podamos añadir una acción que defina un botón con menú asociado (al estilo de los que vemos todos los días en el navegador en los botones "Atrás" y "Adelante"). Lo malo de este tipo es que tiene un menú asociado, y añadirlo en tiempo de "diseño" de la interfaz parece que va a requerir algunos cambios en Twinpanel...