/* * GooCanvas. Copyright (C) 2005 Damon Chaplin. * Released under the GNU LGPL license. See COPYING for details. * * goocanvasimageview.c - view for image item. */ /** * SECTION:goocanvasimageview * @Title: GooCanvasImageView * @Short_Description: a view for a #GooCanvasImage item. * * #GooCanvasImageView represents a view of a #GooCanvasImage item. * * It implements the #GooCanvasItemView interface, so you can use the * #GooCanvasItemView functions such as goo_canvas_item_view_get_item() * and goo_canvas_item_view_get_bounds(). * * Applications do not normally need to create item views themselves, as * they are created automatically by #GooCanvasView when needed. * * To respond to events such as mouse clicks in the ellipse view you can * connect to one of the #GooCanvasItemView signals such as * #GooCanvasItemView::button-press-event. You can connect to these signals * when the view is created. (See goo_canvas_view_get_item_view() and * #GooCanvasView::item-view-created.) */ #include #include #include "goocanvasimageview.h" #include "goocanvasimage.h" #include "goocanvasview.h" static void canvas_item_view_interface_init (GooCanvasItemViewIface *iface); G_DEFINE_TYPE_WITH_CODE (GooCanvasImageView, goo_canvas_image_view, GOO_TYPE_CANVAS_ITEM_VIEW_SIMPLE, G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_VIEW, canvas_item_view_interface_init)) static void goo_canvas_image_view_class_init (GooCanvasImageViewClass *klass) { } static void goo_canvas_image_view_init (GooCanvasImageView *image_view) { } /** * goo_canvas_image_view_new: * @canvas_view: the canvas view. * @parent_view: the parent view. * @image: the image item. * * Creates a new #GooCanvasImageView for the given #GooCanvasImage item. * * This is not normally used by application code, as the views are created * automatically by #GooCanvasView. * * Returns: a new #GooCanvasImageView. **/ GooCanvasItemView* goo_canvas_image_view_new (GooCanvasView *canvas_view, GooCanvasItemView *parent_view, GooCanvasImage *image) { GooCanvasItemViewSimple *view; view = g_object_new (GOO_TYPE_CANVAS_IMAGE_VIEW, NULL); view->canvas_view = canvas_view; view->parent_view = parent_view; view->item = g_object_ref (image); goo_canvas_item_view_simple_setup_accessibility (view); g_signal_connect (image, "changed", G_CALLBACK (goo_canvas_item_view_simple_item_changed), view); return (GooCanvasItemView*) view; } static GooCanvasItemView* goo_canvas_image_view_get_item_view_at (GooCanvasItemView *view, gdouble x, gdouble y, cairo_t *cr, gboolean is_pointer_event, gboolean parent_visible) { GooCanvasItemViewSimple *simple_view = (GooCanvasItemViewSimple*) view; GooCanvasItemSimple *simple = simple_view->item; GooCanvasImage *image = (GooCanvasImage*) simple; GooCanvasItemView *found_view = view; double user_x = x, user_y = y; if (simple_view->flags & GOO_CANVAS_ITEM_VIEW_NEED_UPDATE) goo_canvas_item_view_ensure_updated (view); /* Check if the item should receive events. Note that we don't take image transparency into account here at present. */ if (is_pointer_event) { if (simple->pointer_events == GOO_CANVAS_EVENTS_NONE) return NULL; if (simple->pointer_events & GOO_CANVAS_EVENTS_VISIBLE_MASK && (!parent_visible || simple->visibility == GOO_CANVAS_ITEM_INVISIBLE || (simple->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD && simple_view->canvas_view->scale < simple->visibility_threshold))) return NULL; } cairo_save (cr); if (simple->transform) cairo_transform (cr, simple->transform); if (simple_view->transform) cairo_transform (cr, simple_view->transform); cairo_device_to_user (cr, &user_x, &user_y); if (user_x < image->x || (user_x > image->x + image->width) || user_y < image->y || (user_y > image->y + image->height)) found_view = NULL; cairo_restore (cr); return found_view; } static void goo_canvas_image_view_update (GooCanvasItemView *view, gboolean entire_tree, cairo_t *cr, GooCanvasBounds *bounds) { GooCanvasItemViewSimple *simple_view = (GooCanvasItemViewSimple*) view; GooCanvasItemSimple *simple = simple_view->item; GooCanvasImage *image = (GooCanvasImage*) simple; if (entire_tree || (simple_view->flags & GOO_CANVAS_ITEM_VIEW_NEED_UPDATE)) { simple_view->flags &= ~GOO_CANVAS_ITEM_VIEW_NEED_UPDATE; cairo_save (cr); if (simple->transform) cairo_transform (cr, simple->transform); if (simple_view->transform) cairo_transform (cr, simple_view->transform); /* Request a redraw of the existing bounds. */ goo_canvas_view_request_redraw (simple_view->canvas_view, &simple_view->bounds); /* Compute the new bounds. */ simple_view->bounds.x1 = image->x; simple_view->bounds.y1 = image->y; simple_view->bounds.x2 = image->x + image->width; simple_view->bounds.y2 = image->y + image->height; goo_canvas_item_simple_user_bounds_to_device (simple, cr, &simple_view->bounds); /* Request a redraw of the new bounds. */ goo_canvas_view_request_redraw (simple_view->canvas_view, &simple_view->bounds); cairo_restore (cr); } *bounds = simple_view->bounds; } static void goo_canvas_image_view_paint (GooCanvasItemView *view, cairo_t *cr, GooCanvasBounds *bounds, gdouble scale) { GooCanvasItemViewSimple *simple_view = (GooCanvasItemViewSimple*) view; GooCanvasItemSimple *simple = simple_view->item; GooCanvasImage *image = (GooCanvasImage*) simple; cairo_matrix_t matrix; if (!image->pattern) return; /* Check if the item should be visible. */ if (simple->visibility == GOO_CANVAS_ITEM_INVISIBLE || (simple->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD && scale < simple->visibility_threshold)) return; cairo_save (cr); if (simple->transform) cairo_transform (cr, simple->transform); if (simple_view->transform) cairo_transform (cr, simple_view->transform); goo_canvas_item_simple_set_fill_options (simple, cr); cairo_set_source (cr, image->pattern); cairo_matrix_init_translate (&matrix, -image->x, -image->y); cairo_pattern_set_matrix (image->pattern, &matrix); cairo_rectangle (cr, image->x, image->y, image->width, image->height); cairo_fill (cr); /* Using cairo_paint() is much slower, so I guess we shouldn't. */ /*cairo_paint (cr);*/ cairo_restore (cr); } static void canvas_item_view_interface_init (GooCanvasItemViewIface *iface) { iface->get_item_view_at = goo_canvas_image_view_get_item_view_at; iface->update = goo_canvas_image_view_update; iface->paint = goo_canvas_image_view_paint; }