[gimp] app: add an "update" signal to GimpCanvasItem
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add an "update" signal to GimpCanvasItem
- Date: Fri, 1 Oct 2010 16:58:07 +0000 (UTC)
commit d9cd9f8a0725cb9514dc44af9de61a9a493e6e69
Author: Michael Natterer <mitch gimp org>
Date: Fri Oct 1 17:13:00 2010 +0200
app: add an "update" signal to GimpCanvasItem
which gets emitted when the item wants to be redrawn:
- Emit "update" it when any item property changes
- Groups connect to their children and forward "update" for them
- The shell connects to its group of canvas items and exposed
the affected area
- Remove gimp_display_shell_expose_item()
- Move all the shell's item group code into gimpdisplayshell-items.c
app/display/gimpcanvasgroup.c | 41 ++++++++++++++++
app/display/gimpcanvasitem.c | 79 +++++++++++++++++++++++++++----
app/display/gimpcanvasitem.h | 5 ++
app/display/gimpdisplayshell-expose.c | 51 +++++++-------------
app/display/gimpdisplayshell-expose.h | 4 +-
app/display/gimpdisplayshell-handlers.c | 25 +---------
app/display/gimpdisplayshell-items.c | 65 +++++++++++++++++++++++--
app/display/gimpdisplayshell-items.h | 3 +
app/display/gimpdisplayshell.c | 22 +-------
9 files changed, 202 insertions(+), 93 deletions(-)
---
diff --git a/app/display/gimpcanvasgroup.c b/app/display/gimpcanvasgroup.c
index 641d6f4..ad123e6 100644
--- a/app/display/gimpcanvasgroup.c
+++ b/app/display/gimpcanvasgroup.c
@@ -72,6 +72,9 @@ static void gimp_canvas_group_draw (GimpCanvasItem *item,
cairo_t *cr);
static GdkRegion * gimp_canvas_group_get_extents (GimpCanvasItem *item,
GimpDisplayShell *shell);
+static void gimp_canvas_group_child_update (GimpCanvasItem *item,
+ GdkRegion *region,
+ GimpCanvasGroup *group);
G_DEFINE_TYPE (GimpCanvasGroup, gimp_canvas_group, GIMP_TYPE_CANVAS_ITEM)
@@ -222,6 +225,17 @@ gimp_canvas_group_get_extents (GimpCanvasItem *item,
return region;
}
+static void
+gimp_canvas_group_child_update (GimpCanvasItem *item,
+ GdkRegion *region,
+ GimpCanvasGroup *group)
+{
+ g_signal_emit_by_name (group, "update", region);
+}
+
+
+/* public functions */
+
GimpCanvasItem *
gimp_canvas_group_new (GimpDisplayShell *shell)
{
@@ -237,6 +251,7 @@ gimp_canvas_group_add_item (GimpCanvasGroup *group,
GimpCanvasItem *item)
{
GimpCanvasGroupPrivate *private;
+ GdkRegion *region;
g_return_if_fail (GIMP_IS_CANVAS_GROUP (group));
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
@@ -251,6 +266,18 @@ gimp_canvas_group_add_item (GimpCanvasGroup *group,
gimp_canvas_item_suspend_filling (item);
private->items = g_list_append (private->items, g_object_ref (item));
+
+ region = gimp_canvas_item_get_extents (item);
+
+ if (region)
+ {
+ g_signal_emit_by_name (group, "update", region);
+ gdk_region_destroy (region);
+ }
+
+ g_signal_connect (item, "update",
+ G_CALLBACK (gimp_canvas_group_child_update),
+ group);
}
void
@@ -258,6 +285,7 @@ gimp_canvas_group_remove_item (GimpCanvasGroup *group,
GimpCanvasItem *item)
{
GimpCanvasGroupPrivate *private;
+ GdkRegion *region;
g_return_if_fail (GIMP_IS_CANVAS_GROUP (group));
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
@@ -267,6 +295,19 @@ gimp_canvas_group_remove_item (GimpCanvasGroup *group,
g_return_if_fail (g_list_find (private->items, item));
private->items = g_list_remove (private->items, item);
+
+ region = gimp_canvas_item_get_extents (item);
+
+ if (region)
+ {
+ g_signal_emit_by_name (group, "update", region);
+ gdk_region_destroy (region);
+ }
+
+ g_signal_handlers_disconnect_by_func (item,
+ gimp_canvas_group_child_update,
+ group);
+
g_object_unref (item);
}
diff --git a/app/display/gimpcanvasitem.c b/app/display/gimpcanvasitem.c
index b58bcb9..e493955 100644
--- a/app/display/gimpcanvasitem.c
+++ b/app/display/gimpcanvasitem.c
@@ -23,9 +23,11 @@
#include <gegl.h>
#include <gtk/gtk.h>
+#include "libgimpmath/gimpmath.h"
+
#include "display-types.h"
-#include "libgimpmath/gimpmath.h"
+#include "core/gimpmarshal.h"
#include "gimpcanvasitem.h"
#include "gimpdisplayshell.h"
@@ -40,6 +42,12 @@ enum
PROP_HIGHLIGHT
};
+enum
+{
+ UPDATE,
+ LAST_SIGNAL
+};
+
typedef struct _GimpCanvasItemPrivate GimpCanvasItemPrivate;
@@ -69,6 +77,10 @@ static void gimp_canvas_item_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
+static void
+ gimp_canvas_item_dispatch_properties_changed (GObject *object,
+ guint n_pspecs,
+ GParamSpec **pspecs);
static void gimp_canvas_item_real_draw (GimpCanvasItem *item,
GimpDisplayShell *shell,
@@ -88,20 +100,34 @@ G_DEFINE_TYPE (GimpCanvasItem, gimp_canvas_item,
#define parent_class gimp_canvas_item_parent_class
+static guint item_signals[LAST_SIGNAL] = { 0 };
+
static void
gimp_canvas_item_class_init (GimpCanvasItemClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->constructed = gimp_canvas_item_constructed;
- object_class->set_property = gimp_canvas_item_set_property;
- object_class->get_property = gimp_canvas_item_get_property;
-
- klass->draw = gimp_canvas_item_real_draw;
- klass->get_extents = gimp_canvas_item_real_get_extents;
- klass->stroke = gimp_canvas_item_real_stroke;
- klass->fill = gimp_canvas_item_real_fill;
+ object_class->constructed = gimp_canvas_item_constructed;
+ object_class->set_property = gimp_canvas_item_set_property;
+ object_class->get_property = gimp_canvas_item_get_property;
+ object_class->dispatch_properties_changed = gimp_canvas_item_dispatch_properties_changed;
+
+ klass->update = NULL;
+ klass->draw = gimp_canvas_item_real_draw;
+ klass->get_extents = gimp_canvas_item_real_get_extents;
+ klass->stroke = gimp_canvas_item_real_stroke;
+ klass->fill = gimp_canvas_item_real_fill;
+
+ item_signals[UPDATE] =
+ g_signal_new ("update",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpCanvasItemClass, update),
+ NULL, NULL,
+ gimp_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
g_object_class_install_property (object_class, PROP_SHELL,
g_param_spec_object ("shell",
@@ -203,6 +229,41 @@ gimp_canvas_item_get_property (GObject *object,
}
static void
+gimp_canvas_item_dispatch_properties_changed (GObject *object,
+ guint n_pspecs,
+ GParamSpec **pspecs)
+{
+ GimpCanvasItem *item = GIMP_CANVAS_ITEM (object);
+ GdkRegion *before;
+ GdkRegion *region;
+
+ before = gimp_canvas_item_get_extents (item);
+
+ G_OBJECT_CLASS (parent_class)->dispatch_properties_changed (object,
+ n_pspecs,
+ pspecs);
+
+ region = gimp_canvas_item_get_extents (item);
+
+ if (! region)
+ {
+ region = before;
+ }
+ else if (before)
+ {
+ gdk_region_union (region, before);
+ gdk_region_destroy (before);
+ }
+
+ if (region)
+ {
+ g_signal_emit (object, item_signals[UPDATE], 0,
+ region);
+ gdk_region_destroy (region);
+ }
+}
+
+static void
gimp_canvas_item_real_draw (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr)
diff --git a/app/display/gimpcanvasitem.h b/app/display/gimpcanvasitem.h
index f878550..61867d4 100644
--- a/app/display/gimpcanvasitem.h
+++ b/app/display/gimpcanvasitem.h
@@ -44,6 +44,11 @@ struct _GimpCanvasItemClass
{
GimpObjectClass parent_class;
+ /* signals */
+ void (* update) (GimpCanvasItem *item,
+ GdkRegion *region);
+
+ /* virtual functions */
void (* draw) (GimpCanvasItem *item,
GimpDisplayShell *shell,
cairo_t *cr);
diff --git a/app/display/gimpdisplayshell-expose.c b/app/display/gimpdisplayshell-expose.c
index eb959b0..b8361db 100644
--- a/app/display/gimpdisplayshell-expose.c
+++ b/app/display/gimpdisplayshell-expose.c
@@ -44,43 +44,15 @@ gimp_display_shell_expose_area (GimpDisplayShell *shell,
gtk_widget_queue_draw_area (shell->canvas, x, y, w, h);
}
-static void
-gimp_display_shell_expose_region (GimpDisplayShell *shell,
- gdouble x1,
- gdouble y1,
- gdouble x2,
- gdouble y2,
- gint border)
-{
- const gint x = floor (x1);
- const gint y = floor (y1);
- const gint w = ceil (x2) - x;
- const gint h = ceil (y2) - y;
-
- gimp_display_shell_expose_area (shell,
- x - border,
- y - border,
- w + 2 * border,
- h + 2 * border);
-}
-
void
-gimp_display_shell_expose_item (GimpDisplayShell *shell,
- GimpCanvasItem *item)
+gimp_display_shell_expose_region (GimpDisplayShell *shell,
+ GdkRegion *region)
{
- GdkRegion *region;
-
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
- g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
+ g_return_if_fail (region != NULL);
- region = gimp_canvas_item_get_extents (item);
-
- if (region)
- {
- gdk_window_invalidate_region (gtk_widget_get_window (shell->canvas),
- region, TRUE);
- gdk_region_destroy (region);
- }
+ gdk_window_invalidate_region (gtk_widget_get_window (shell->canvas),
+ region, TRUE);
}
void
@@ -95,10 +67,21 @@ gimp_display_shell_expose_vectors (GimpDisplayShell *shell,
if (gimp_vectors_bounds (vectors, &x1, &y1, &x2, &y2))
{
+ gint x, y, w, h;
+
gimp_display_shell_transform_xy_f (shell, x1, y1, &x1, &y1);
gimp_display_shell_transform_xy_f (shell, x2, y2, &x2, &y2);
- gimp_display_shell_expose_region (shell, x1, y1, x2, y2, 2);
+ x = floor (x1);
+ y = floor (y1);
+ w = ceil (x2) - x;
+ h = ceil (y2) - y;
+
+ gimp_display_shell_expose_area (shell,
+ x - 2,
+ y - 2,
+ w + 4,
+ h + 4);
}
}
diff --git a/app/display/gimpdisplayshell-expose.h b/app/display/gimpdisplayshell-expose.h
index 58ea2fb..96a59cb 100644
--- a/app/display/gimpdisplayshell-expose.h
+++ b/app/display/gimpdisplayshell-expose.h
@@ -24,8 +24,8 @@ void gimp_display_shell_expose_area (GimpDisplayShell *shell,
gint y,
gint w,
gint h);
-void gimp_display_shell_expose_item (GimpDisplayShell *shell,
- GimpCanvasItem *item);
+void gimp_display_shell_expose_region (GimpDisplayShell *shell,
+ GdkRegion *region);
void gimp_display_shell_expose_vectors (GimpDisplayShell *shell,
GimpVectors *vectors);
void gimp_display_shell_expose_full (GimpDisplayShell *shell);
diff --git a/app/display/gimpdisplayshell-handlers.c b/app/display/gimpdisplayshell-handlers.c
index 6b53a1f..6838caa 100644
--- a/app/display/gimpdisplayshell-handlers.c
+++ b/app/display/gimpdisplayshell-handlers.c
@@ -550,8 +550,6 @@ gimp_display_shell_guide_add_handler (GimpImage *image,
gimp_canvas_proxy_group_add_item (group, guide, item);
g_object_unref (item);
-
- gimp_display_shell_expose_item (shell, item);
}
static void
@@ -560,11 +558,6 @@ gimp_display_shell_guide_remove_handler (GimpImage *image,
GimpDisplayShell *shell)
{
GimpCanvasProxyGroup *group = GIMP_CANVAS_PROXY_GROUP (shell->guides);
- GimpCanvasItem *item;
-
- item = gimp_canvas_proxy_group_get_item (group, guide);
-
- gimp_display_shell_expose_item (shell, item);
gimp_canvas_proxy_group_remove_item (group, guide);
}
@@ -579,14 +572,10 @@ gimp_display_shell_guide_move_handler (GimpImage *image,
item = gimp_canvas_proxy_group_get_item (group, guide);
- gimp_display_shell_expose_item (shell, item);
-
g_object_set (item,
"orientation", gimp_guide_get_orientation (guide),
"position", gimp_guide_get_position (guide),
NULL);
-
- gimp_display_shell_expose_item (shell, item);
}
static void
@@ -619,8 +608,6 @@ gimp_display_shell_sample_point_add_handler (GimpImage *image,
g_object_set (item,
"index", i,
NULL);
-
- gimp_display_shell_expose_item (shell, item);
}
}
@@ -630,14 +617,9 @@ gimp_display_shell_sample_point_remove_handler (GimpImage *image,
GimpDisplayShell *shell)
{
GimpCanvasProxyGroup *group = GIMP_CANVAS_PROXY_GROUP (shell->sample_points);
- GimpCanvasItem *item;
GList *list;
gint i;
- item = gimp_canvas_proxy_group_get_item (group, sample_point);
-
- gimp_display_shell_expose_item (shell, item);
-
gimp_canvas_proxy_group_remove_item (group, sample_point);
for (list = gimp_image_get_sample_points (image), i = 1;
@@ -645,14 +627,13 @@ gimp_display_shell_sample_point_remove_handler (GimpImage *image,
list = g_list_next (list), i++)
{
GimpSamplePoint *sample_point = list->data;
+ GimpCanvasItem *item;
item = gimp_canvas_proxy_group_get_item (group, sample_point);
g_object_set (item,
"index", i,
NULL);
-
- gimp_display_shell_expose_item (shell, item);
}
}
@@ -666,14 +647,10 @@ gimp_display_shell_sample_point_move_handler (GimpImage *image,
item = gimp_canvas_proxy_group_get_item (group, sample_point);
- gimp_display_shell_expose_item (shell, item);
-
g_object_set (item,
"x", sample_point->x,
"y", sample_point->y,
NULL);
-
- gimp_display_shell_expose_item (shell, item);
}
static void
diff --git a/app/display/gimpdisplayshell-items.c b/app/display/gimpdisplayshell-items.c
index d98e1ae..adbc643 100644
--- a/app/display/gimpdisplayshell-items.c
+++ b/app/display/gimpdisplayshell-items.c
@@ -24,12 +24,60 @@
#include "display-types.h"
-#include "gimpcanvasgroup.h"
+#include "gimpcanvasproxygroup.h"
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-expose.h"
#include "gimpdisplayshell-items.h"
+/* local function prototypes */
+
+static void gimp_display_shell_item_update (GimpCanvasItem *item,
+ GdkRegion *region,
+ GimpDisplayShell *shell);
+
+
+/* public functions */
+
+void
+gimp_display_shell_items_init (GimpDisplayShell *shell)
+{
+ g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+
+ shell->canvas_item = gimp_canvas_group_new (shell);
+
+ shell->guides = gimp_canvas_proxy_group_new (shell);
+ gimp_display_shell_add_item (shell, shell->guides);
+ g_object_unref (shell->guides);
+
+ shell->sample_points = gimp_canvas_proxy_group_new (shell);
+ gimp_display_shell_add_item (shell, shell->sample_points);
+ g_object_unref (shell->sample_points);
+
+ g_signal_connect (shell->canvas_item, "update",
+ G_CALLBACK (gimp_display_shell_item_update),
+ shell);
+}
+
+void
+gimp_display_shell_items_free (GimpDisplayShell *shell)
+{
+ g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
+
+ if (shell->canvas_item)
+ {
+ g_signal_handlers_disconnect_by_func (shell->canvas_item,
+ gimp_display_shell_item_update,
+ shell);
+
+ g_object_unref (shell->canvas_item);
+ shell->canvas_item = NULL;
+
+ shell->guides = NULL;
+ shell->sample_points = NULL;
+ }
+}
+
void
gimp_display_shell_add_item (GimpDisplayShell *shell,
GimpCanvasItem *item)
@@ -38,8 +86,6 @@ gimp_display_shell_add_item (GimpDisplayShell *shell,
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
gimp_canvas_group_add_item (GIMP_CANVAS_GROUP (shell->canvas_item), item);
-
- gimp_display_shell_expose_item (shell, item);
}
void
@@ -49,7 +95,16 @@ gimp_display_shell_remove_item (GimpDisplayShell *shell,
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (GIMP_IS_CANVAS_ITEM (item));
- gimp_display_shell_expose_item (shell, item);
-
gimp_canvas_group_remove_item (GIMP_CANVAS_GROUP (shell->canvas_item), item);
}
+
+
+/* private functions */
+
+static void
+gimp_display_shell_item_update (GimpCanvasItem *item,
+ GdkRegion *region,
+ GimpDisplayShell *shell)
+{
+ gimp_display_shell_expose_region (shell, region);
+}
diff --git a/app/display/gimpdisplayshell-items.h b/app/display/gimpdisplayshell-items.h
index 59b040f..4b5b9b3 100644
--- a/app/display/gimpdisplayshell-items.h
+++ b/app/display/gimpdisplayshell-items.h
@@ -22,6 +22,9 @@
#define __GIMP_DISPLAY_SHELL_ITEMS_H__
+void gimp_display_shell_items_init (GimpDisplayShell *shell);
+void gimp_display_shell_items_free (GimpDisplayShell *shell);
+
void gimp_display_shell_add_item (GimpDisplayShell *shell,
GimpCanvasItem *item);
void gimp_display_shell_remove_item (GimpDisplayShell *shell,
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index 36dd15e..06bbcd5 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -53,7 +53,6 @@
#include "tools/tool_manager.h"
#include "gimpcanvas.h"
-#include "gimpcanvasproxygroup.h"
#include "gimpdisplay.h"
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-appearance.h"
@@ -64,6 +63,7 @@
#include "gimpdisplayshell-expose.h"
#include "gimpdisplayshell-filter.h"
#include "gimpdisplayshell-handlers.h"
+#include "gimpdisplayshell-items.h"
#include "gimpdisplayshell-progress.h"
#include "gimpdisplayshell-render.h"
#include "gimpdisplayshell-scale.h"
@@ -291,17 +291,7 @@ gimp_display_shell_init (GimpDisplayShell *shell)
GIMP_DISPLAY_RENDER_BUF_WIDTH,
GIMP_DISPLAY_RENDER_BUF_HEIGHT);
- shell->canvas_item = gimp_canvas_group_new (shell);
-
- shell->guides = gimp_canvas_proxy_group_new (shell);
- gimp_canvas_group_add_item (GIMP_CANVAS_GROUP (shell->canvas_item),
- shell->guides);
- g_object_unref (shell->guides);
-
- shell->sample_points = gimp_canvas_proxy_group_new (shell);
- gimp_canvas_group_add_item (GIMP_CANVAS_GROUP (shell->canvas_item),
- shell->sample_points);
- g_object_unref (shell->sample_points);
+ gimp_display_shell_items_init (shell);
shell->icon_size = 32;
@@ -806,13 +796,7 @@ gimp_display_shell_dispose (GObject *object)
shell->mask = NULL;
}
- if (shell->canvas_item)
- {
- g_object_unref (shell->canvas_item);
- shell->canvas_item = NULL;
- shell->guides = NULL;
- shell->sample_points = NULL;
- }
+ gimp_display_shell_items_free (shell);
if (shell->event_history)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]