app: refactor the canvas items to return a GdkRegion as extents

instead of invalidating the canvas themselves.
This commit is contained in:
Michael Natterer
2010-09-19 23:20:36 +02:00
parent 69a898cc9f
commit 96bdf1fec5
3 changed files with 114 additions and 63 deletions

View File

@ -22,18 +22,36 @@
#include "display-types.h" #include "display-types.h"
#include "libgimpmath/gimpmath.h"
#include "gimpcanvasitem.h" #include "gimpcanvasitem.h"
#include "gimpdisplayshell.h" #include "gimpdisplayshell.h"
#include "gimpdisplayshell-style.h" #include "gimpdisplayshell-style.h"
typedef struct _GimpCanvasItemPrivate GimpCanvasItemPrivate;
struct _GimpCanvasItemPrivate
{
gdouble extents_x;
gdouble extents_y;
gdouble extents_width;
gdouble extents_height;
};
#define GET_PRIVATE(item) \
G_TYPE_INSTANCE_GET_PRIVATE (item, \
GIMP_TYPE_CANVAS_ITEM, \
GimpCanvasItemPrivate)
/* local function prototypes */ /* local function prototypes */
static void gimp_canvas_item_real_draw (GimpCanvasItem *item, static void gimp_canvas_item_real_draw (GimpCanvasItem *item,
GimpDisplayShell *shell, GimpDisplayShell *shell,
cairo_t *cr); cairo_t *cr);
static void gimp_canvas_item_real_invalidate (GimpCanvasItem *item, static GdkRegion * gimp_canvas_item_real_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell); GimpDisplayShell *shell);
G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item, G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item,
@ -45,8 +63,10 @@ G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item,
static void static void
gimp_canvas_item_class_init (GimpCanvasItemClass *klass) gimp_canvas_item_class_init (GimpCanvasItemClass *klass)
{ {
klass->draw = gimp_canvas_item_real_draw; klass->draw = gimp_canvas_item_real_draw;
klass->invalidate = gimp_canvas_item_real_invalidate; klass->get_extents = gimp_canvas_item_real_get_extents;
g_type_class_add_private (klass, sizeof (GimpCanvasItemPrivate));
} }
static void static void
@ -62,11 +82,19 @@ gimp_canvas_item_real_draw (GimpCanvasItem *item,
g_warn_if_reached (); g_warn_if_reached ();
} }
static void static GdkRegion *
gimp_canvas_item_real_invalidate (GimpCanvasItem *item, gimp_canvas_item_real_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell) GimpDisplayShell *shell)
{ {
g_warn_if_reached (); GimpCanvasItemPrivate *private = GET_PRIVATE (item);
GdkRectangle rectangle;
rectangle.x = floor (private->extents_x);
rectangle.y = floor (private->extents_y);
rectangle.width = ceil (private->extents_width);
rectangle.height = ceil (private->extents_height);
return gdk_region_rectangle (&rectangle);
} }
@ -88,14 +116,32 @@ gimp_canvas_item_draw (GimpCanvasItem *item,
cairo_restore (cr); cairo_restore (cr);
} }
void GdkRegion *
gimp_canvas_item_invalidate (GimpCanvasItem *item, gimp_canvas_item_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell) GimpDisplayShell *shell)
{ {
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item)); g_return_val_if_fail (GIMP_IS_CANVAS_ITEM (item), NULL);
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
GIMP_CANVAS_ITEM_GET_CLASS (item)->invalidate (item, shell); return GIMP_CANVAS_ITEM_GET_CLASS (item)->get_extents (item, shell);
}
/* protexted functions */
void
_gimp_canvas_item_set_extents (GimpCanvasItem *item,
gdouble x,
gdouble y,
gdouble width,
gdouble height)
{
GimpCanvasItemPrivate *private = GET_PRIVATE (item);
private->extents_x = x;
private->extents_y = y;
private->extents_width = width;
private->extents_height = height;
} }
void void

View File

@ -45,31 +45,36 @@ struct _GimpCanvasItemClass
{ {
GimpObjectClass parent_class; GimpObjectClass parent_class;
void (* draw) (GimpCanvasItem *item, void (* draw) (GimpCanvasItem *item,
GimpDisplayShell *shell, GimpDisplayShell *shell,
cairo_t *cr); cairo_t *cr);
void (* invalidate) (GimpCanvasItem *item, GdkRegion * (* get_extents) (GimpCanvasItem *item,
GimpDisplayShell *shell); GimpDisplayShell *shell);
}; };
GType gimp_canvas_item_get_type (void) G_GNUC_CONST; GType gimp_canvas_item_get_type (void) G_GNUC_CONST;
void gimp_canvas_item_draw (GimpCanvasItem *item, void gimp_canvas_item_draw (GimpCanvasItem *item,
GimpDisplayShell *shell, GimpDisplayShell *shell,
cairo_t *cr); cairo_t *cr);
void gimp_canvas_item_invalidate (GimpCanvasItem *item, GdkRegion * gimp_canvas_item_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell); GimpDisplayShell *shell);
/* protected */ /* protected */
void _gimp_canvas_item_stroke (GimpCanvasItem *item, void _gimp_canvas_item_set_extents (GimpCanvasItem *item,
GimpDisplayShell *shell, gdouble x,
cairo_t *cr); gdouble y,
void _gimp_canvas_item_fill (GimpCanvasItem *item, gdouble width,
GimpDisplayShell *shell, gdouble height);
cairo_t *cr); void _gimp_canvas_item_stroke (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
void _gimp_canvas_item_fill (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
#endif /* __GIMP_CANVAS_ITEM_H__ */ #endif /* __GIMP_CANVAS_ITEM_H__ */

View File

@ -61,19 +61,19 @@ struct _GimpCanvasRectanglePrivate
/* local function prototypes */ /* local function prototypes */
static void gimp_canvas_rectangle_set_property (GObject *object, static void gimp_canvas_rectangle_set_property (GObject *object,
guint property_id, guint property_id,
const GValue *value, const GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_canvas_rectangle_get_property (GObject *object, static void gimp_canvas_rectangle_get_property (GObject *object,
guint property_id, guint property_id,
GValue *value, GValue *value,
GParamSpec *pspec); GParamSpec *pspec);
static void gimp_canvas_rectangle_draw (GimpCanvasItem *item, static void gimp_canvas_rectangle_draw (GimpCanvasItem *item,
GimpDisplayShell *shell, GimpDisplayShell *shell,
cairo_t *cr); cairo_t *cr);
static void gimp_canvas_rectangle_invalidate (GimpCanvasItem *item, static GdkRegion * gimp_canvas_rectangle_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell); GimpDisplayShell *shell);
G_DEFINE_TYPE (GimpCanvasRectangle, gimp_canvas_rectangle, G_DEFINE_TYPE (GimpCanvasRectangle, gimp_canvas_rectangle,
@ -92,7 +92,7 @@ gimp_canvas_rectangle_class_init (GimpCanvasRectangleClass *klass)
object_class->get_property = gimp_canvas_rectangle_get_property; object_class->get_property = gimp_canvas_rectangle_get_property;
item_class->draw = gimp_canvas_rectangle_draw; item_class->draw = gimp_canvas_rectangle_draw;
item_class->invalidate = gimp_canvas_rectangle_invalidate; item_class->get_extents = gimp_canvas_rectangle_get_extents;
g_object_class_install_property (object_class, PROP_X, g_object_class_install_property (object_class, PROP_X,
g_param_spec_double ("x", NULL, NULL, g_param_spec_double ("x", NULL, NULL,
@ -251,25 +251,25 @@ gimp_canvas_rectangle_draw (GimpCanvasItem *item,
cairo_rectangle (cr, x, y, w, h); cairo_rectangle (cr, x, y, w, h);
if (private->filled) if (private->filled)
_gimp_canvas_item_fill (item, shell, cr); {
_gimp_canvas_item_set_extents (item, x, y, w, h);
_gimp_canvas_item_fill (item, shell, cr);
}
else else
_gimp_canvas_item_stroke (item, shell, cr); {
_gimp_canvas_item_set_extents (item, x - 1.5, y - 1.5, w + 3.0, h + 3.0);
_gimp_canvas_item_stroke (item, shell, cr);
}
} }
static void static GdkRegion *
gimp_canvas_rectangle_invalidate (GimpCanvasItem *item, gimp_canvas_rectangle_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell) GimpDisplayShell *shell)
{ {
GimpCanvasRectanglePrivate *private = GET_PRIVATE (item); /* TODO: for large unfilled rectangles, construct a region which
gdouble x, y; * contains only the four sides
gdouble w, h; */
return GIMP_CANVAS_ITEM_CLASS (parent_class)->get_extents (item, shell);
gimp_canvas_rectangle_transform (item, shell, &x, &y, &w, &h);
if (private->filled)
gimp_display_shell_expose_area (shell, x, y, w, h);
else
gimp_display_shell_expose_area (shell, x - 1.5, y - 1.5, w + 1.5, h + 1.5);
} }
GimpCanvasItem * GimpCanvasItem *