Desarrollando widgets con
GTK+
Carlos Garnacho
[email protected]
Desarrollando widgets con GTK+
Introducción
Toolkit grafico usado en GNOME
Multiplataforma
Linux (como no)
Windows
MacOS
Surgió del GIMP
Desarrollando widgets con GTK+
“Tipos” de widgets
Desde el punto de vista del
desarrollo
Widgets “simples”
no reutilizan otros widgets
label, entry, ...
Widgets compuestos
reutilizan otros widgets para
implementar partes
notebook, treeview, dialog, ...
Desarrollando widgets con GTK+
Widgets compuestos
Reutilizan otros componentes
graficos
normalmente heredan de
GtkContainer
GtkContainer es una clase abstracta
Por conveniencia puedes querer
heredar de otros widgets
Desarrollando widgets con GTK+
Creando los widgets internos
gtk_widget_push_composite_child ();
label = gtk_label_new (“blah”);
gtk_widget_set_parent (label,
GTK_WIDGET (container));
gtk_widget_show (data->label);
button = gtk_button_new_from_stock (GTK_STOCK_OK)
gtk_widget_set_parent (button,
GTK_WIDGET (container));
gtk_widget_show (data->label);
gtk_widget_pop_composite_child ()
Reserva de tamaño
Un poco artesanal
calcular tamaño de contenidos,
widgets internos, etc... teniendo
en cuenta la distribución de
estos, espaciado, bordes...
pasar ancho y alto en la
estructura GtkRequisition.
Desarrollando widgets con GTK+
Reserva de tamaño (y 2)
/* añadir bordes */
requisition->width = 2 * container->border_width;
requisition->height = 2 * container->border_width;
/* recorrer widgets */
while (children_widgets)
{
/* pedir tamaño al widget hijo */
gtk_widget_size_request (children_widgets->data,
&child_widget_req);
requisition->height += child_widget_req.height;
requisition->width = MAX (requisition->width,
child_widget_req.width);
}
children_widgets = children_widgets->next;
Desarrollando widgets con GTK+
Reserva de tamaño (y 3)
Debemos controlar cuando
creemos que ha podido cambiar
el tamaño de nuestro widget
gtk_widget_queue_resize()
Asignación de tamaño
Igualmente artesanal
al método ::size-allocate se le
pasa un GtkAllocation
a partir de ese GtkAllocation,
nuestra implementación debe
decir a los widgets internos el
tamaño deseado para ellos,
teniendo en cuenta espaciado,
bordes, etc...
Desarrollando widgets con GTK+
Asignación de tamaño (y 2)
/* guardar allocation en widget */
widget->allocation = *allocation;
/* inicializar child_alloc con los valores fijos */
child_alloc = *allocation;
child_alloc.x += container->border_width;
child_alloc.width -= 2 * container->border_width;
child_alloc.y += container->border_width;
/* recorrer widgets */
while (children_widgets)
{
child_alloc.height =
((GtkWidget *) children_widgets->data)->
requisition.height;
gtk_widget_size_allocate (children_widgets->data,
&child_alloc);
child_alloc.y += child_alloc.height;
children_widgets = children_widgets->next;
}
Controlando la visibilidad
de los widgets
Como diseñadores del widget
podemos no querer que
determinados widgets se
muestren siempre
Debemos proteger esto contra
cosas como:
gtk_widget_show_all()
gtk_widget_show() sobre el widget
Desarrollando widgets con GTK+
Controlando la visibilidad
de los widgets (y 2)
gtk_widget_map() / unmap()
gtk_widget_set_child_visible()
Widgets “simples”
pueden ser bastante complejos
controlar todos los aspectos
ventanas X, layering, ...
dibujado
...
Desarrollando widgets con GTK+
Realize / Unrealize
Realize: Fase de reserva de
recursos de X
Los recursos se reservan cuando
son necesarios.
Unrealize: destrucción de dichos
recursos
widget->window normalmente es
el GdkWindow del widget padre.
Hay que usar los recursos
sabiamente.
GdkWindow
Abstracción de una ventana X
en otras plataformas, se “fuerza”
un poco la misma filosofia
Tipos:
Input/Output: muestran información
y reciben eventos.
Input only: invisibles, solo reciben
eventos.
Desarrollando widgets con GTK+
Widgets con ventana y sin ventana
Sin ventana
tienen flag GTK_WIDGET_NO_WINDOW
para dibujarse usan el GdkWindow del
widget padre
Con ventana
crean una ventana propia
Ambos pueden definir además
ventanas INPUT_ONLY
Expose
Fase de dibujado
cuando un area de la ventana es
invalidada, este método se llama
sobre el area que necesita
redibujarse
Debe ser amigable con recursos
No dibujar cosas que no hacen falta
redibujarse
usar clipping areas
Desarrollando widgets con GTK+
GtkStyle
define el estilo usado por GTK+
struct con la gama de colores
definida por el theme
puede cambiar en cualquier
momento, escuchar a ::style-set
Tambien contiene funciones de
dibujado de elementos básicos
gtk_paint_box()
gtk_paint_layout()
gtk_paint_hline() / vline()
...
Manejo con el teclado
Hay que definir como se va a
comportar el widget
Tab / Shift+Tab
flechas
señal ::focus
gtk_widget_grab_focus()
gtk_paint_focus()
Desarrollando widgets con GTK+
Bonus Points
Bonus points
soporte lenguajes RTL/LTR
Cambios en el estilo de GTK+
Stock icons (solo si no usas
GtkImage)
propiedades de estilo de tu widget
Accesibilidad
Esto merece otra charla
Miscelanea
::popup-menu
...
Desarrollando widgets con GTK+
¿Preguntas?
Desarrollando widgets con GTK+
¿¿En serio no hay preguntas??
Desarrollando widgets con GTK+
Gracias por venir