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 "libgimpmath/gimpmath.h"
#include "gimpcanvasitem.h"
#include "gimpdisplayshell.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 */
static void gimp_canvas_item_real_draw (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
static void gimp_canvas_item_real_invalidate (GimpCanvasItem *item,
GimpDisplayShell *shell);
static void gimp_canvas_item_real_draw (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
static GdkRegion * gimp_canvas_item_real_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell);
G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item,
@ -45,8 +63,10 @@ G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item,
static void
gimp_canvas_item_class_init (GimpCanvasItemClass *klass)
{
klass->draw = gimp_canvas_item_real_draw;
klass->invalidate = gimp_canvas_item_real_invalidate;
klass->draw = gimp_canvas_item_real_draw;
klass->get_extents = gimp_canvas_item_real_get_extents;
g_type_class_add_private (klass, sizeof (GimpCanvasItemPrivate));
}
static void
@ -62,11 +82,19 @@ gimp_canvas_item_real_draw (GimpCanvasItem *item,
g_warn_if_reached ();
}
static void
gimp_canvas_item_real_invalidate (GimpCanvasItem *item,
GimpDisplayShell *shell)
static GdkRegion *
gimp_canvas_item_real_get_extents (GimpCanvasItem *item,
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);
}
void
gimp_canvas_item_invalidate (GimpCanvasItem *item,
GimpDisplayShell *shell)
GdkRegion *
gimp_canvas_item_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell)
{
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_val_if_fail (GIMP_IS_CANVAS_ITEM (item), NULL);
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

View File

@ -45,31 +45,36 @@ struct _GimpCanvasItemClass
{
GimpObjectClass parent_class;
void (* draw) (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
void (* invalidate) (GimpCanvasItem *item,
GimpDisplayShell *shell);
void (* draw) (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
GdkRegion * (* get_extents) (GimpCanvasItem *item,
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,
GimpDisplayShell *shell,
cairo_t *cr);
void gimp_canvas_item_invalidate (GimpCanvasItem *item,
GimpDisplayShell *shell);
void gimp_canvas_item_draw (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
GdkRegion * gimp_canvas_item_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell);
/* protected */
void _gimp_canvas_item_stroke (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
void _gimp_canvas_item_fill (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
void _gimp_canvas_item_set_extents (GimpCanvasItem *item,
gdouble x,
gdouble y,
gdouble width,
gdouble height);
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__ */

View File

@ -61,19 +61,19 @@ struct _GimpCanvasRectanglePrivate
/* local function prototypes */
static void gimp_canvas_rectangle_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_canvas_rectangle_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_canvas_rectangle_draw (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
static void gimp_canvas_rectangle_invalidate (GimpCanvasItem *item,
GimpDisplayShell *shell);
static void gimp_canvas_rectangle_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_canvas_rectangle_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_canvas_rectangle_draw (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
static GdkRegion * gimp_canvas_rectangle_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell);
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;
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_param_spec_double ("x", NULL, NULL,
@ -251,25 +251,25 @@ gimp_canvas_rectangle_draw (GimpCanvasItem *item,
cairo_rectangle (cr, x, y, w, h);
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
_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
gimp_canvas_rectangle_invalidate (GimpCanvasItem *item,
GimpDisplayShell *shell)
static GdkRegion *
gimp_canvas_rectangle_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell)
{
GimpCanvasRectanglePrivate *private = GET_PRIVATE (item);
gdouble x, y;
gdouble w, h;
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);
/* TODO: for large unfilled rectangles, construct a region which
* contains only the four sides
*/
return GIMP_CANVAS_ITEM_CLASS (parent_class)->get_extents (item, shell);
}
GimpCanvasItem *