[gegl-gtk] GeglGtkView: Move most logic to a private class
- From: Jon Nordby <jonnor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl-gtk] GeglGtkView: Move most logic to a private class
- Date: Sun, 9 Oct 2011 12:00:46 +0000 (UTC)
commit 6c15741bc4d8d0437e6f0abb9f74f225832f9d9e
Author: Jon Nordby <jononor gmail com>
Date: Wed Oct 5 21:19:02 2011 +0200
GeglGtkView: Move most logic to a private class
gegl-gtk/Makefile.am | 5 +-
gegl-gtk/gegl-gtk-view.c | 299 +++++++++------------------------------
gegl-gtk/gegl-gtk-view.h | 6 +-
gegl-gtk/internal/view-helper.c | 294 ++++++++++++++++++++++++++++++++++++++
gegl-gtk/internal/view-helper.h | 81 +++++++++++
5 files changed, 450 insertions(+), 235 deletions(-)
---
diff --git a/gegl-gtk/Makefile.am b/gegl-gtk/Makefile.am
index bfb9d77..15a0eb8 100644
--- a/gegl-gtk/Makefile.am
+++ b/gegl-gtk/Makefile.am
@@ -4,10 +4,13 @@ headers = gegl-gtk.h gegl-gtk-view.h
sources = gegl-gtk-view.c
INCLUDES = $(GTK_CFLAGS) $(GEGL_CFLAGS)
+internal_headers = internal/view-helper.h
+internal_sources = internal/view-helper.c
+
gegl_gtk_includedir=$(includedir)/gegl-gtk$(GEGL_GTK_GTK_VERSION)-$(GEGL_GTK_API_VERSION)
gegl_gtk_include_HEADERS = $(headers)
-gegl_gtk_SOURCES = $(headers) $(sources)
+gegl_gtk_SOURCES = $(headers) $(sources) $(internal_headers) $(internal_sources)
gegl_gtk_LIBADD = $(GTK_LIBS) $(GEGL_LIBS)
gegl_gtk_CFLAGS = $(INCLUDES) $(CFLAGS)
diff --git a/gegl-gtk/gegl-gtk-view.c b/gegl-gtk/gegl-gtk-view.c
index cc8d860..0259eba 100644
--- a/gegl-gtk/gegl-gtk-view.c
+++ b/gegl-gtk/gegl-gtk-view.c
@@ -18,13 +18,26 @@
#include "config.h"
-#include <math.h>
-#include <babl/babl.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <gegl.h>
#include "gegl-gtk-view.h"
+#include "internal/view-helper.h"
+
+
+/**
+ * This class is responsible for providing the public interface
+ * consumers expect of the view widget, and for rendering onto the widget.
+ * Tracking changes in the GeglNode, dealing with model<->view transformations
+ * et.c. is delegated to the internal/private class ViewHelper.
+ *
+ * This separation of concerns keeps the classes small and "stupid", and
+ * allows to test a lot of functionality without having to instantiate
+ * a widget and rely on the presence and behaviour of a windowing system.
+ */
+
+G_DEFINE_TYPE (GeglGtkView, gegl_gtk_view, GTK_TYPE_DRAWING_AREA)
enum
{
@@ -36,31 +49,15 @@ enum
PROP_BLOCK
};
-enum
-{
- SIGNAL_REDRAW,
- N_SIGNALS
-};
-
-typedef struct _GeglGtkViewPrivate
+static ViewHelper *
+get_private(GeglGtkView *self)
{
- GeglNode *node;
- gfloat x;
- gfloat y;
- gdouble scale;
- gboolean block; /* blocking render */
-
- guint monitor_id;
- GeglProcessor *processor;
-} GeglGtkViewPrivate;
+ return VIEW_HELPER(self->priv);
+}
+#define GET_PRIVATE(self) (get_private(self))
-G_DEFINE_TYPE (GeglGtkView, gegl_gtk_view, GTK_TYPE_DRAWING_AREA)
-#define GEGL_GTK_VIEW_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GEGL_GTK_TYPE_VIEW, GeglGtkViewPrivate))
-
-static guint gegl_gtk_view_signals[N_SIGNALS] = { 0 };
static void gegl_gtk_view_class_init (GeglGtkViewClass *klass);
static void gegl_gtk_view_init (GeglGtkView *self);
@@ -73,6 +70,7 @@ static void get_property (GObject *gobject,
guint prop_id,
GValue *value,
GParamSpec *pspec);
+
#ifdef HAVE_GTK2
static gboolean expose_event (GtkWidget *widget,
GdkEventExpose *event);
@@ -82,11 +80,12 @@ static gboolean draw (GtkWidget * widget,
cairo_t *cr);
#endif
-static void redraw_event (GeglGtkView *view,
- GeglRectangle *rect,
- gpointer data);
-static void gegl_gtk_view_repaint (GeglGtkView *view);
+static void
+trigger_redraw(ViewHelper* priv, GeglRectangle *rect, GeglGtkView *view);
+static void
+size_allocate(GtkWidget *widget, GdkRectangle *allocation, gpointer user_data);
+
static void
gegl_gtk_view_class_init (GeglGtkViewClass * klass)
@@ -141,89 +140,26 @@ gegl_gtk_view_class_init (GeglGtkViewClass * klass)
FALSE,
G_PARAM_READWRITE));
- /* Emitted when a redraw is needed, with the area that needs redrawing.
- * Exposed so that it can be tested. */
- gegl_gtk_view_signals[SIGNAL_REDRAW] = g_signal_new ("redraw",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__BOXED,
- G_TYPE_NONE, 1,
- GEGL_TYPE_RECTANGLE);
-
- g_type_class_add_private (klass, sizeof (GeglGtkViewPrivate));
}
static void
gegl_gtk_view_init (GeglGtkView *self)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (self);
- priv->node = NULL;
- priv->x = 0;
- priv->y = 0;
- priv->scale = 1.0;
- priv->monitor_id = 0;
- priv->processor = NULL;
-
- g_signal_connect(self, "redraw", G_CALLBACK (redraw_event), NULL);
-}
-
-static void
-finalize (GObject *gobject)
-{
- GeglGtkView * self = GEGL_GTK_VIEW (gobject);
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (self);
-
- if (priv->monitor_id)
- {
- g_source_remove (priv->monitor_id);
- priv->monitor_id = 0;
- }
-
- if (priv->node)
- g_object_unref (priv->node);
-
- if (priv->processor)
- g_object_unref (priv->processor);
-
- G_OBJECT_CLASS (gegl_gtk_view_parent_class)->finalize (gobject);
-}
-
-static void
-computed_event (GeglNode *self,
- GeglRectangle *rect,
- GeglGtkView *view)
-{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (view);
- gint x = priv->scale * (rect->x) - priv->x;
- gint y = priv->scale * (rect->y) - priv->y;
- gint w = ceil (priv->scale * rect->width);
- gint h = ceil (priv->scale * rect->height);
- GeglRectangle redraw_rect = {x, y, w, h};
-
- g_signal_emit (view, gegl_gtk_view_signals[SIGNAL_REDRAW],
- 0, &redraw_rect, NULL);
+ self->priv = (GeglGtkViewPrivate *)view_helper_new();
+ g_signal_connect(self->priv, "redraw-needed", G_CALLBACK (trigger_redraw), (gpointer)self);
+
+ g_signal_connect(self, "size-allocate", G_CALLBACK (size_allocate), NULL);
}
static void
-redraw_event (GeglGtkView *view,
- GeglRectangle *rect,
- gpointer data)
+finalize (GObject *gobject)
{
- gtk_widget_queue_draw_area (GTK_WIDGET (view),
- rect->x, rect->y,
- rect->width, rect->height);
-}
+ GeglGtkView *self = GEGL_GTK_VIEW (gobject);
+ g_object_unref(G_OBJECT(self->priv));
-static void
-invalidated_event (GeglNode *self,
- GeglRectangle *rect,
- GeglGtkView *view)
-{
- gegl_gtk_view_repaint (view);
+ G_OBJECT_CLASS(gegl_gtk_view_parent_class)->finalize(gobject);
}
static void
@@ -233,7 +169,7 @@ set_property (GObject *gobject,
GParamSpec *pspec)
{
GeglGtkView *self = GEGL_GTK_VIEW (gobject);
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (self);
+ ViewHelper *priv = GET_PRIVATE (self);
switch (property_id)
{
@@ -266,7 +202,7 @@ get_property (GObject *gobject,
GParamSpec *pspec)
{
GeglGtkView *self = GEGL_GTK_VIEW (gobject);
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (self);
+ ViewHelper *priv = GET_PRIVATE (self);
switch (property_id)
{
@@ -291,38 +227,24 @@ get_property (GObject *gobject,
}
}
+/* Trigger a redraw */
static void
-draw_implementation (GeglGtkViewPrivate *priv, cairo_t *cr, GdkRectangle *rect)
+trigger_redraw (ViewHelper *priv,
+ GeglRectangle *rect,
+ GeglGtkView *view)
{
- cairo_surface_t *surface = NULL;
- guchar *buf = NULL;
- GeglRectangle roi;
-
- roi.x = priv->x + rect->x;
- roi.y = priv->y + rect->y;
- roi.width = rect->width;
- roi.height = rect->height;
-
- buf = g_malloc ((roi.width) * (roi.height) * 4);
-
- gegl_node_blit (priv->node,
- priv->scale,
- &roi,
- babl_format ("B'aG'aR'aA u8"),
- (gpointer)buf,
- GEGL_AUTO_ROWSTRIDE,
- GEGL_BLIT_CACHE | (priv->block ? 0 : GEGL_BLIT_DIRTY));
-
- surface = cairo_image_surface_create_for_data (buf,
- CAIRO_FORMAT_ARGB32,
- roi.width, roi.height,
- roi.width*4);
- cairo_set_source_surface (cr, surface, rect->x, rect->y);
- cairo_paint (cr);
-
- cairo_surface_destroy (surface);
- g_free (buf);
+ if (rect->width < 0 || rect->height < 0)
+ gtk_widget_queue_draw(GTK_WIDGET(view));
+ else
+ gtk_widget_queue_draw_area(GTK_WIDGET(view),
+ rect->x, rect->y, rect->width, rect->height);
+}
+static void
+size_allocate(GtkWidget *widget, GdkRectangle *allocation, gpointer user_data)
+{
+ GeglGtkView *self = GEGL_GTK_VIEW (widget);
+ view_helper_set_allocation(GET_PRIVATE(self), allocation);
}
#ifdef HAVE_GTK3
@@ -330,7 +252,7 @@ static gboolean
draw (GtkWidget * widget, cairo_t *cr)
{
GeglGtkView *view = GEGL_GTK_VIEW (widget);
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (view);
+ ViewHelper *priv = GET_PRIVATE (view);
GdkRectangle rect;
if (!priv->node)
@@ -338,9 +260,9 @@ draw (GtkWidget * widget, cairo_t *cr)
gdk_cairo_get_clip_rectangle (cr, &rect);
- draw_implementation (priv, cr, &rect);
+ view_helper_draw (priv, cr, &rect);
- gegl_gtk_view_repaint (view);
+ view_helper_repaint (priv); /* Only needed due to possible allocation changes? */
return FALSE;
}
@@ -352,7 +274,7 @@ expose_event (GtkWidget *widget,
GdkEventExpose *event)
{
GeglGtkView *view = GEGL_GTK_VIEW (widget);
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (view);
+ ViewHelper *priv = GET_PRIVATE (view);
cairo_t *cr;
GdkRectangle rect;
@@ -364,60 +286,16 @@ expose_event (GtkWidget *widget,
cairo_clip (cr);
gdk_region_get_clipbox (event->region, &rect);
- draw_implementation (priv, cr, &rect);
+ view_helper_draw (priv, cr, &rect);
+
cairo_destroy (cr);
- gegl_gtk_view_repaint (view);
+ view_helper_repaint (priv); /* Only needed due to possible allocation changes? */
return FALSE;
}
#endif
-static gboolean
-task_monitor (GeglGtkView *view)
-{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (view);
- if (priv->processor==NULL)
- return FALSE;
- if (gegl_processor_work (priv->processor, NULL))
- return TRUE;
-
- priv->monitor_id = 0;
-
- return FALSE;
-}
-
-void
-gegl_gtk_view_repaint (GeglGtkView *view)
-{
- GtkWidget *widget = GTK_WIDGET (view);
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (view);
- GeglRectangle roi;
- GtkAllocation allocation;
-
- roi.x = priv->x / priv->scale;
- roi.y = priv->y / priv->scale;
- gtk_widget_get_allocation (widget, &allocation);
- roi.width = ceil(allocation.width / priv->scale+1);
- roi.height = ceil(allocation.height / priv->scale+1);
-
- if (priv->monitor_id == 0)
- {
- priv->monitor_id = g_idle_add_full (G_PRIORITY_LOW,
- (GSourceFunc) task_monitor, view,
- NULL);
-
- if (priv->processor == NULL)
- {
- if (priv->node)
- priv->processor = gegl_node_new_processor (priv->node, &roi);
- }
- }
-
- if (priv->processor)
- gegl_processor_set_rectangle (priv->processor, &roi);
-}
-
GeglGtkView *
gegl_gtk_view_new()
@@ -437,30 +315,7 @@ gegl_gtk_view_new_for_node(GeglNode *node)
void
gegl_gtk_view_set_node(GeglGtkView *self, GeglNode *node)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (self);
-
- if (priv->node == node)
- return;
-
- if (priv->node)
- g_object_unref (priv->node);
-
- if (node) {
- g_object_ref (node);
- priv->node = node;
-
- g_signal_connect_object (priv->node, "computed",
- G_CALLBACK (computed_event),
- self, 0);
- g_signal_connect_object (priv->node, "invalidated",
- G_CALLBACK (invalidated_event),
- self, 0);
-
- gegl_gtk_view_repaint (self);
-
- } else
- priv->node = NULL;
-
+ view_helper_set_node(GET_PRIVATE (self), node);
}
/**
@@ -471,63 +326,41 @@ gegl_gtk_view_set_node(GeglGtkView *self, GeglNode *node)
GeglNode *
gegl_gtk_view_get_node(GeglGtkView *self)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE (self);
- return priv->node;
+ return view_helper_get_node(GET_PRIVATE(self));
}
void
gegl_gtk_view_set_scale(GeglGtkView *self, float scale)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE(self);
-
- if (priv->scale == scale)
- return;
-
- priv->scale = scale;
- gtk_widget_queue_draw(GTK_WIDGET (self));
+ view_helper_set_scale(GET_PRIVATE(self), scale);
}
float
gegl_gtk_view_get_scale(GeglGtkView *self)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE(self);
- return priv->scale;
+ return view_helper_get_scale(GET_PRIVATE(self));
}
void
gegl_gtk_view_set_x(GeglGtkView *self, float x)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE(self);
-
- if (priv->x == x)
- return;
-
- priv->x = x;
- gtk_widget_queue_draw(GTK_WIDGET (self));
+ view_helper_set_x(GET_PRIVATE(self), x);
}
float
gegl_gtk_view_get_x(GeglGtkView *self)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE(self);
- return priv->x;
+ return view_helper_get_x(GET_PRIVATE(self));
}
void
gegl_gtk_view_set_y(GeglGtkView *self, float y)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE(self);
-
- if (priv->y == y)
- return;
-
- priv->y = y;
- gtk_widget_queue_draw(GTK_WIDGET (self));
+ view_helper_set_y(GET_PRIVATE(self), y);
}
float
gegl_gtk_view_get_y(GeglGtkView *self)
{
- GeglGtkViewPrivate *priv = GEGL_GTK_VIEW_GET_PRIVATE(self);
- return priv->y;
+ return view_helper_get_y(GET_PRIVATE(self));
}
diff --git a/gegl-gtk/gegl-gtk-view.h b/gegl-gtk/gegl-gtk-view.h
index 03dbe1e..9ea904b 100644
--- a/gegl-gtk/gegl-gtk-view.h
+++ b/gegl-gtk/gegl-gtk-view.h
@@ -34,14 +34,18 @@ G_BEGIN_DECLS
typedef struct _GeglGtkView GeglGtkView;
typedef struct _GeglGtkViewClass GeglGtkViewClass;
+typedef struct _ViewHelper GeglGtkViewPrivate;
+
struct _GeglGtkView
{
+ /*< private >*/
GtkDrawingArea parent_instance;
-
+ GeglGtkViewPrivate *priv; /* Can't use the GType private mechanism for GObjects */
};
struct _GeglGtkViewClass
{
+ /*< private >*/
GtkDrawingAreaClass parent_class;
};
diff --git a/gegl-gtk/internal/view-helper.c b/gegl-gtk/internal/view-helper.c
new file mode 100644
index 0000000..682d6d6
--- /dev/null
+++ b/gegl-gtk/internal/view-helper.c
@@ -0,0 +1,294 @@
+/* This file is part of GEGL-GTK
+ *
+ * GEGL-GTK is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL-GTK 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL-GTK; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2003, 2004, 2006 Ãyvind KolÃs <pippin gimp org>
+ */
+
+#include "view-helper.h"
+
+#include <math.h>
+#include <babl/babl.h>
+
+
+G_DEFINE_TYPE (ViewHelper, view_helper, G_TYPE_OBJECT)
+
+
+enum
+{
+ SIGNAL_REDRAW_NEEDED,
+ N_SIGNALS
+};
+
+static guint view_helper_signals[N_SIGNALS] = { 0 };
+
+static void
+finalize (GObject *gobject);
+
+static void
+view_helper_class_init (ViewHelperClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = finalize;
+
+ /* Emitted when a redraw is needed, with the area that needs redrawing. */
+ view_helper_signals[SIGNAL_REDRAW_NEEDED] = g_signal_new ("redraw-needed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GEGL_TYPE_RECTANGLE);
+}
+
+static void
+view_helper_init (ViewHelper *self)
+{
+ self->node = NULL;
+ self->x = 0;
+ self->y = 0;
+ self->scale = 1.0;
+ self->monitor_id = 0;
+ self->processor = NULL;
+}
+
+static void
+finalize (GObject *gobject)
+{
+ ViewHelper *self = VIEW_HELPER(gobject);
+
+ if (self->monitor_id)
+ {
+ g_source_remove (self->monitor_id);
+ self->monitor_id = 0;
+ }
+
+ if (self->node)
+ g_object_unref (self->node);
+
+ if (self->processor)
+ g_object_unref (self->processor);
+}
+
+
+static void
+invalidated_event (GeglNode *node,
+ GeglRectangle *rect,
+ ViewHelper *self)
+{
+ view_helper_repaint (self);
+}
+
+static gboolean
+task_monitor (ViewHelper *self)
+{
+ if (self->processor==NULL)
+ return FALSE;
+ if (gegl_processor_work (self->processor, NULL))
+ return TRUE;
+
+ self->monitor_id = 0;
+
+ return FALSE;
+}
+
+
+/* When the GeglNode has been computed,
+ * find out which area in the view changed and emit the
+ * "redraw" signal to notify it that a redraw is needed */
+static void
+computed_event (GeglNode *node,
+ GeglRectangle *rect,
+ ViewHelper *self)
+{
+ gint x = self->scale * (rect->x) - self->x;
+ gint y = self->scale * (rect->y) - self->y;
+ gint w = ceil (self->scale * rect->width);
+ gint h = ceil (self->scale * rect->height);
+ GeglRectangle redraw_rect = {x, y, w, h};
+
+ g_signal_emit (self, view_helper_signals[SIGNAL_REDRAW_NEEDED],
+ 0, &redraw_rect, NULL);
+}
+
+ViewHelper *
+view_helper_new(void)
+{
+ return VIEW_HELPER(g_object_new(VIEW_HELPER_TYPE, NULL));
+}
+
+/* Draw the view of the GeglNode to the provided cairo context,
+ * taking into account transformations et.c.
+ * @rect the bounding box of the area to draw in view coordinates
+ *
+ * For instance called by widget during the draw/expose */
+void
+view_helper_draw (ViewHelper *self, cairo_t *cr, GdkRectangle *rect)
+{
+ cairo_surface_t *surface = NULL;
+ guchar *buf = NULL;
+ GeglRectangle roi;
+
+ roi.x = self->x + rect->x;
+ roi.y = self->y + rect->y;
+ roi.width = rect->width;
+ roi.height = rect->height;
+
+ buf = g_malloc ((roi.width) * (roi.height) * 4);
+
+ gegl_node_blit (self->node,
+ self->scale,
+ &roi,
+ babl_format ("B'aG'aR'aA u8"),
+ (gpointer)buf,
+ GEGL_AUTO_ROWSTRIDE,
+ GEGL_BLIT_CACHE | (self->block ? 0 : GEGL_BLIT_DIRTY));
+
+ surface = cairo_image_surface_create_for_data (buf,
+ CAIRO_FORMAT_ARGB32,
+ roi.width, roi.height,
+ roi.width*4);
+ cairo_set_source_surface (cr, surface, rect->x, rect->y);
+ cairo_paint (cr);
+
+ cairo_surface_destroy (surface);
+ g_free (buf);
+
+}
+
+void
+view_helper_set_allocation(ViewHelper *self, GdkRectangle *allocation)
+{
+ self->allocation = *allocation;
+ view_helper_repaint(self);
+}
+
+/* Trigger processing of the GeglNode */
+void
+view_helper_repaint (ViewHelper *self)
+{
+ GeglRectangle roi;
+
+ roi.x = self->x / self->scale;
+ roi.y = self->y / self->scale;
+
+ roi.width = ceil(self->allocation.width / self->scale+1);
+ roi.height = ceil(self->allocation.height / self->scale+1);
+
+ if (self->monitor_id == 0)
+ {
+ self->monitor_id = g_idle_add_full (G_PRIORITY_LOW,
+ (GSourceFunc) task_monitor, self,
+ NULL);
+
+ if (self->processor == NULL)
+ {
+ if (self->node)
+ self->processor = gegl_node_new_processor (self->node, &roi);
+ }
+ }
+
+ if (self->processor)
+ gegl_processor_set_rectangle (self->processor, &roi);
+}
+
+void
+invalidate(ViewHelper *self)
+{
+ GeglRectangle redraw_rect = {0, 0, -1, -1}; /* Indicates full redraw */
+ g_signal_emit (self, view_helper_signals[SIGNAL_REDRAW_NEEDED],
+ 0, &redraw_rect, NULL);
+}
+
+void
+view_helper_set_node(ViewHelper *self, GeglNode *node)
+{
+ if (self->node == node)
+ return;
+
+ if (self->node)
+ g_object_unref (self->node);
+
+ if (node) {
+ g_object_ref (node);
+ self->node = node;
+
+ g_signal_connect_object (self->node, "computed",
+ G_CALLBACK (computed_event),
+ self, 0);
+ g_signal_connect_object (self->node, "invalidated",
+ G_CALLBACK (invalidated_event),
+ self, 0);
+
+ view_helper_repaint (self);
+
+ } else
+ self->node = NULL;
+}
+
+GeglNode *
+view_helper_get_node(ViewHelper *self)
+{
+ return self->node;
+}
+
+void
+view_helper_set_scale(ViewHelper *self, float scale)
+{
+ if (self->scale == scale)
+ return;
+
+ self->scale = scale;
+ invalidate(self);
+}
+
+float
+view_helper_get_scale(ViewHelper *self)
+{
+ return self->scale;
+}
+
+void
+view_helper_set_x(ViewHelper *self, float x)
+{
+ if (self->x == x)
+ return;
+
+ self->x = x;
+ invalidate(self);
+}
+
+float
+view_helper_get_x(ViewHelper *self)
+{
+ return self->x;
+}
+
+void
+view_helper_set_y(ViewHelper *self, float y)
+{
+ if (self->y == y)
+ return;
+
+ self->y = y;
+ invalidate(self);
+}
+
+float
+view_helper_get_y(ViewHelper *self)
+{
+ return self->y;
+}
diff --git a/gegl-gtk/internal/view-helper.h b/gegl-gtk/internal/view-helper.h
new file mode 100644
index 0000000..ec07835
--- /dev/null
+++ b/gegl-gtk/internal/view-helper.h
@@ -0,0 +1,81 @@
+/* This file is part of GEGL-GTK
+ *
+ * GEGL-GTK is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * GEGL-GTK 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GEGL-GTK; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2003, 2004, 2006 Ãyvind KolÃs <pippin gimp org>
+ */
+
+#ifndef __VIEW_HELPER_H__
+#define __VIEW_HELPER_H__
+
+#include <glib-object.h>
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define VIEW_HELPER_TYPE (view_helper_get_type ())
+#define VIEW_HELPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIEW_HELPER_TYPE, ViewHelper))
+#define VIEW_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VIEW_HELPER_TYPE, ViewHelperClass))
+#define IS_VIEW_HELPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIEW_HELPER_TYPE))
+#define IS_VIEW_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIEW_HELPER_TYPE))
+#define VIEW_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VIEW_HELPER_TYPE, ViewHelperClass))
+
+typedef struct _ViewHelper ViewHelper;
+typedef struct _ViewHelperClass ViewHelperClass;
+
+struct _ViewHelper
+{
+ GObject parent_instance;
+
+ GeglNode *node;
+ gfloat x;
+ gfloat y;
+ gdouble scale;
+ gboolean block; /* blocking render */
+ guint monitor_id;
+ GeglProcessor *processor;
+ GdkRectangle allocation;
+};
+
+struct _ViewHelperClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType view_helper_get_type (void) G_GNUC_CONST;
+
+ViewHelper *view_helper_new(void);
+void view_helper_node_changed(ViewHelper *self);
+void view_helper_repaint(ViewHelper *self);
+void view_helper_draw(ViewHelper *self, cairo_t *cr, GdkRectangle *rect);
+void view_helper_set_allocation(ViewHelper *self, GdkRectangle *allocation);
+
+void view_helper_set_node(ViewHelper *self, GeglNode *node);
+GeglNode *view_helper_get_node(ViewHelper *self);
+
+void view_helper_set_scale(ViewHelper *self, float scale);
+float view_helper_get_scale(ViewHelper *self);
+
+void view_helper_set_x(ViewHelper *self, float x);
+float view_helper_get_x(ViewHelper *self);
+
+void view_helper_set_y(ViewHelper *self, float y);
+float view_helper_get_y(ViewHelper *self);
+
+
+G_END_DECLS
+
+#endif /* __VIEW_HELPER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]