X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkdrawingarea.c;h=b1bcb49169a64a62abc6ba3a0eedf3925b04f262;hb=fd51c8f5e9d6fb68c8e81b9b1e2ab80931f963f0;hp=8f4eaff4ebe48ef82c75d4783047736eeecfc9a3;hpb=48d8ec36d5440994f8ccb985f5186f660ac11148;p=~andy%2Fgtk diff --git a/gtk/gtkdrawingarea.c b/gtk/gtkdrawingarea.c index 8f4eaff4e..b1bcb4916 100644 --- a/gtk/gtkdrawingarea.c +++ b/gtk/gtkdrawingarea.c @@ -2,63 +2,138 @@ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . */ /* - * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ +#include "config.h" #include "gtkdrawingarea.h" +#include "gtkintl.h" +#include "gtkstylecontext.h" -static void gtk_drawing_area_class_init (GtkDrawingAreaClass *klass); -static void gtk_drawing_area_init (GtkDrawingArea *darea); +/** + * SECTION:gtkdrawingarea + * @Short_description: A widget for custom user interface elements + * @Title: GtkDrawingArea + * @See_also: #GtkImage + * + * The #GtkDrawingArea widget is used for creating custom user interface + * elements. It's essentially a blank widget; you can draw on it. After + * creating a drawing area, the application may want to connect to: + * + * + * + * + * Mouse and button press signals to respond to input from + * the user. (Use gtk_widget_add_events() to enable events + * you wish to receive.) + * + * + * + * + * The #GtkWidget::realize signal to take any necessary actions + * when the widget is instantiated on a particular display. + * (Create GDK resources in response to this signal.) + * + * + * + * + * The #GtkWidget::configure-event signal to take any necessary + * actions when the widget changes size. + * + * + * + * + * The #GtkWidget::draw signal to handle redrawing the + * contents of the widget. + * + * + * + * + * The following code portion demonstrates using a drawing + * area to display a circle in the normal widget foreground + * color. + * + * Note that GDK automatically clears the exposed area to the + * background color before sending the expose event, and that + * drawing is implicitly clipped to the exposed area. + * + * + * Simple GtkDrawingArea usage + * + * gboolean + * draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data) + * { + * guint width, height; + * GdkRGBA color; + * + * width = gtk_widget_get_allocated_width (widget); + * height = gtk_widget_get_allocated_height (widget); + * cairo_arc (cr, + * width / 2.0, height / 2.0, + * MIN (width, height) / 2.0, + * 0, 2 * G_PI); + * + * gtk_style_context_get_color (gtk_widget_get_style_context (widget), + * 0, + * &color); + * gdk_cairo_set_source_rgba (cr, &color); + * + * cairo_fill (cr); + * + * return FALSE; + * } + * [...] + * GtkWidget *drawing_area = gtk_drawing_area_new (); + * gtk_widget_set_size_request (drawing_area, 100, 100); + * g_signal_connect (G_OBJECT (drawing_area), "draw", + * G_CALLBACK (draw_callback), NULL); + * + * + * + * Draw signals are normally delivered when a drawing area first comes + * onscreen, or when it's covered by another window and then uncovered. + * You can also force an expose event by adding to the "damage region" + * of the drawing area's window; gtk_widget_queue_draw_area() and + * gdk_window_invalidate_rect() are equally good ways to do this. + * You'll then get a draw signal for the invalid region. + * + * The available routines for drawing are documented on the GDK Drawing Primitives page + * and the cairo documentation. + * + * To receive mouse events on a drawing area, you will need to enable + * them with gtk_widget_add_events(). To receive keyboard events, you + * will need to set the "can-focus" property on the drawing area, and you + * should probably draw some user-visible indication that the drawing + * area is focused. Use gtk_widget_has_focus() in your expose event + * handler to decide whether to draw the focus indicator. See + * gtk_render_focus() for one way to draw focus. + */ + static void gtk_drawing_area_realize (GtkWidget *widget); static void gtk_drawing_area_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); + GtkAllocation *allocation); static void gtk_drawing_area_send_configure (GtkDrawingArea *darea); - -GtkType -gtk_drawing_area_get_type (void) -{ - static GtkType drawing_area_type = 0; - - if (!drawing_area_type) - { - static const GtkTypeInfo drawing_area_info = - { - "GtkDrawingArea", - sizeof (GtkDrawingArea), - sizeof (GtkDrawingAreaClass), - (GtkClassInitFunc) gtk_drawing_area_class_init, - (GtkObjectInitFunc) gtk_drawing_area_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - drawing_area_type = gtk_type_unique (GTK_TYPE_WIDGET, &drawing_area_info); - } - - return drawing_area_type; -} +G_DEFINE_TYPE (GtkDrawingArea, gtk_drawing_area, GTK_TYPE_WIDGET) static void gtk_drawing_area_class_init (GtkDrawingAreaClass *class) @@ -72,78 +147,77 @@ gtk_drawing_area_class_init (GtkDrawingAreaClass *class) static void gtk_drawing_area_init (GtkDrawingArea *darea) { - darea->draw_data = NULL; } - +/** + * gtk_drawing_area_new: + * + * Creates a new drawing area. + * + * Returns: a new #GtkDrawingArea + */ GtkWidget* gtk_drawing_area_new (void) { - return GTK_WIDGET (gtk_type_new (GTK_TYPE_DRAWING_AREA)); -} - -void -gtk_drawing_area_size (GtkDrawingArea *darea, - gint width, - gint height) -{ - g_return_if_fail (GTK_IS_DRAWING_AREA (darea)); - - GTK_WIDGET (darea)->requisition.width = width; - GTK_WIDGET (darea)->requisition.height = height; - - gtk_widget_queue_resize (GTK_WIDGET (darea)); + return g_object_new (GTK_TYPE_DRAWING_AREA, NULL); } static void gtk_drawing_area_realize (GtkWidget *widget) { - GtkDrawingArea *darea; + GtkAllocation allocation; + GdkWindow *window; GdkWindowAttr attributes; gint attributes_mask; - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_DRAWING_AREA (widget)); + if (!gtk_widget_get_has_window (widget)) + { + GTK_WIDGET_CLASS (gtk_drawing_area_parent_class)->realize (widget); + } + else + { + gtk_widget_set_realized (widget, TRUE); - darea = GTK_DRAWING_AREA (widget); - GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + gtk_widget_get_allocation (widget, &allocation); - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = widget->allocation.x; - attributes.y = widget->allocation.y; - attributes.width = widget->allocation.width; - attributes.height = widget->allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK; - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; - widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); - gdk_window_set_user_data (widget->window, darea); + window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gtk_widget_register_window (widget, window); + gtk_widget_set_window (widget, window); - widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); + gtk_style_context_set_background (gtk_widget_get_style_context (widget), + window); + } gtk_drawing_area_send_configure (GTK_DRAWING_AREA (widget)); } static void gtk_drawing_area_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) + GtkAllocation *allocation) { - g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_DRAWING_AREA (widget)); g_return_if_fail (allocation != NULL); - widget->allocation = *allocation; + gtk_widget_set_allocation (widget, allocation); - if (GTK_WIDGET_REALIZED (widget)) + if (gtk_widget_get_realized (widget)) { - gdk_window_move_resize (widget->window, - allocation->x, allocation->y, - allocation->width, allocation->height); + if (gtk_widget_get_has_window (widget)) + gdk_window_move_resize (gtk_widget_get_window (widget), + allocation->x, allocation->y, + allocation->width, allocation->height); gtk_drawing_area_send_configure (GTK_DRAWING_AREA (widget)); } @@ -152,18 +226,20 @@ gtk_drawing_area_size_allocate (GtkWidget *widget, static void gtk_drawing_area_send_configure (GtkDrawingArea *darea) { + GtkAllocation allocation; GtkWidget *widget; - GdkEventConfigure event; + GdkEvent *event = gdk_event_new (GDK_CONFIGURE); widget = GTK_WIDGET (darea); + gtk_widget_get_allocation (widget, &allocation); + + event->configure.window = g_object_ref (gtk_widget_get_window (widget)); + event->configure.send_event = TRUE; + event->configure.x = allocation.x; + event->configure.y = allocation.y; + event->configure.width = allocation.width; + event->configure.height = allocation.height; - event.type = GDK_CONFIGURE; - event.window = widget->window; - event.send_event = TRUE; - event.x = widget->allocation.x; - event.y = widget->allocation.y; - event.width = widget->allocation.width; - event.height = widget->allocation.height; - - gtk_widget_event (widget, (GdkEvent*) &event); + gtk_widget_event (widget, event); + gdk_event_free (event); }