Desarrollando widgets con GTK+

Anuncio
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
Descargar