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