gegl r2861 - in trunk: . examples examples/util
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2861 - in trunk: . examples examples/util
- Date: Tue, 6 Jan 2009 15:36:42 +0000 (UTC)
Author: ok
Date: Tue Jan 6 15:36:42 2009
New Revision: 2861
URL: http://svn.gnome.org/viewvc/gegl?rev=2861&view=rev
Log:
Re-added the GeglView class in a subdirectory of the examples code
for now.
* examples/util/: added dir,.. and
* examples/util/gegl-view.c: this and,..
* examples/util/gegl-view.h: this file which originally was in bin/
* examples/gegl-paint.c: changed include paths for gegl-view code.
Added:
trunk/examples/util/
trunk/examples/util/gegl-view.c
trunk/examples/util/gegl-view.h
Modified:
trunk/ChangeLog
trunk/examples/gegl-paint.c
Modified: trunk/examples/gegl-paint.c
==============================================================================
--- trunk/examples/gegl-paint.c (original)
+++ trunk/examples/gegl-paint.c Tue Jan 6 15:36:42 2009
@@ -20,8 +20,8 @@
#include <glib.h>
#include <gegl.h>
#include <gtk/gtk.h>
-#include "../bin/gegl-view.h"
-#include "../bin/gegl-view.c"
+#include "util/gegl-view.h"
+#include "util/gegl-view.c"
#include "property-types/gegl-path.h"
#define HARDNESS 0.2
Added: trunk/examples/util/gegl-view.c
==============================================================================
--- (empty file)
+++ trunk/examples/util/gegl-view.c Tue Jan 6 15:36:42 2009
@@ -0,0 +1,537 @@
+/* This file is part of GEGL editor -- a gtk frontend for GEGL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2003, 2004, 2006 Ãyvind KolÃs
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <babl/babl.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gegl.h"
+#include "gegl-view.h"
+
+enum
+{
+ PROP_0,
+ PROP_NODE,
+ PROP_X,
+ PROP_Y,
+ PROP_SCALE,
+ PROP_BLOCK
+};
+
+
+typedef struct _GeglViewPrivate
+{
+ GeglNode *node;
+ gint x;
+ gint y;
+ gdouble scale;
+ gboolean block; /* blocking render */
+
+ gint screen_x; /* coordinates of drag start */
+ gint screen_y;
+
+ gint orig_x; /* coordinates of drag start */
+ gint orig_y;
+
+ gint start_buf_x; /* coordinates of drag start */
+ gint start_buf_y;
+
+ gint prev_x;
+ gint prev_y;
+ gdouble prev_scale;
+
+ guint monitor_id;
+ GeglProcessor *processor;
+} GeglViewPrivate;
+
+enum
+{
+ DETECTED,
+ LAST_SIGNAL
+};
+
+
+static gint gegl_view_signals[LAST_SIGNAL] = {0, };
+
+
+G_DEFINE_TYPE (GeglView, gegl_view, GTK_TYPE_DRAWING_AREA)
+#define GEGL_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GEGL_TYPE_VIEW, GeglViewPrivate))
+
+static void gegl_view_class_init (GeglViewClass *klass);
+static void gegl_view_init (GeglView *self);
+static void finalize (GObject *gobject);
+static void set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static gboolean motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event);
+static gboolean button_press_event (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean button_release_event (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+
+
+static void
+gegl_view_class_init (GeglViewClass * klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ gobject_class->finalize = finalize;
+ gobject_class->set_property = set_property;
+ gobject_class->get_property = get_property;
+
+ widget_class->motion_notify_event = motion_notify_event;
+ widget_class->button_press_event = button_press_event;
+ widget_class->button_release_event = button_release_event;
+ widget_class->expose_event = expose_event;
+
+ g_object_class_install_property (gobject_class, PROP_X,
+ g_param_spec_int ("x",
+ "X",
+ "X origin",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_Y,
+ g_param_spec_int ("y",
+ "Y",
+ "Y origin",
+ G_MININT, G_MAXINT, 0,
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_SCALE,
+ g_param_spec_double ("scale",
+ "Scale",
+ "Zoom factor",
+ 0.0, 100.0, 1.00,
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_NODE,
+ g_param_spec_object ("node",
+ "Node",
+ "The node to render",
+ G_TYPE_OBJECT,
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, PROP_BLOCK,
+ g_param_spec_boolean ("block",
+ "Blocking render",
+ "Make sure all data requested to blit is generated.",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ gegl_view_signals[DETECTED] =
+ g_signal_new ("detected",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GEGL_TYPE_NODE);
+
+
+ g_type_class_add_private (klass, sizeof (GeglViewPrivate));
+}
+
+static void
+gegl_view_init (GeglView *self)
+{
+ GeglViewPrivate *priv = GEGL_VIEW_GET_PRIVATE (self);
+ priv->node = NULL;
+ priv->x = 0;
+ priv->y = 0;
+ priv->prev_x = -1;
+ priv->prev_y = -1;
+ priv->scale = 1.0;
+ priv->monitor_id = 0;
+ priv->processor = NULL;
+
+ gtk_widget_add_events (GTK_WIDGET (self), (GDK_EXPOSURE_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK));
+}
+
+static void
+finalize (GObject *gobject)
+{
+ GeglView * self = GEGL_VIEW (gobject);
+ GeglViewPrivate *priv = GEGL_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);
+
+ G_OBJECT_CLASS (gegl_view_parent_class)->finalize (gobject);
+}
+
+static void
+computed_event (GeglNode *self,
+ GeglRectangle *rect,
+ GeglView *view)
+{
+ GeglViewPrivate *priv = GEGL_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 + 1);
+ gint h = ceil (priv->scale * rect->height + 1);
+
+ gtk_widget_queue_draw_area (GTK_WIDGET (view), x, y, w, h);
+}
+
+
+static void
+invalidated_event (GeglNode *self,
+ GeglRectangle *rect,
+ GeglView *view)
+{
+ gegl_view_repaint (view);
+}
+
+static void
+set_property (GObject *gobject,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeglView *self = GEGL_VIEW (gobject);
+ GeglViewPrivate *priv = GEGL_VIEW_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_NODE:
+ if (priv->node)
+ {
+#if 0
+ gegl_node_disable_cache (priv->node); /* FIXME: should we really? */
+#endif
+ g_object_unref (priv->node);
+ }
+
+ if (g_value_get_object (value))
+ {
+ priv->node = GEGL_NODE (g_value_dup_object (value));
+
+ 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_view_repaint (self);
+ }
+ else
+ {
+ priv->node = NULL;
+ }
+ break;
+ case PROP_X:
+ priv->x = g_value_get_int (value);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+ break;
+ case PROP_BLOCK:
+ priv->block = g_value_get_boolean (value);
+ break;
+ case PROP_Y:
+ priv->y = g_value_get_int (value);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+ break;
+ case PROP_SCALE:
+ priv->scale = g_value_get_double (value);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+ break;
+ default:
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *gobject,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GeglView *self = GEGL_VIEW (gobject);
+ GeglViewPrivate *priv = GEGL_VIEW_GET_PRIVATE (self);
+
+ switch (property_id)
+ {
+ case PROP_NODE:
+ g_value_set_object (value, priv->node);
+ break;
+ case PROP_X:
+ g_value_set_int (value, priv->x);
+ break;
+ case PROP_BLOCK:
+ g_value_set_boolean (value, priv->block);
+ break;
+ case PROP_Y:
+ g_value_set_int (value, priv->y);
+ break;
+ case PROP_SCALE:
+ g_value_set_double (value, priv->scale);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
+ break;
+ }
+}
+
+static void
+detected_event (GeglView *self,
+ GeglNode *node)
+{
+ g_signal_emit (self, gegl_view_signals[DETECTED], 0, node, NULL, NULL);
+}
+
+static gboolean drag_started = FALSE;
+
+static gboolean
+button_press_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GeglView *view = GEGL_VIEW (widget);
+ GeglViewPrivate *priv = GEGL_VIEW_GET_PRIVATE (view);
+ gint x = event->x;
+ gint y = event->y;
+
+ return FALSE;
+
+ priv->screen_x = x;
+ priv->screen_y = y;
+
+ priv->orig_x = priv->x;
+ priv->orig_y = priv->y;
+
+ priv->start_buf_x = (priv->x + x)/priv->scale;
+ priv->start_buf_y = (priv->y + y)/priv->scale;
+
+ priv->prev_x = x;
+ priv->prev_y = y;
+
+ x = x / priv->scale + priv->x;
+ y = y / priv->scale + priv->y;
+
+ {
+ GeglNode *detected = gegl_node_detect (priv->node,
+ (priv->x + event->x) / priv->scale,
+ (priv->y + event->y) / priv->scale);
+ if (detected)
+ {
+ detected_event (view, detected);
+ }
+ }
+
+ drag_started = TRUE;
+ return TRUE;
+}
+
+static gboolean
+button_release_event (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ drag_started = FALSE;
+ return FALSE;
+}
+
+static gboolean
+motion_notify_event (GtkWidget *widget,
+ GdkEventMotion *event)
+{
+ GeglView *view = GEGL_VIEW (widget);
+ GeglViewPrivate *priv = GEGL_VIEW_GET_PRIVATE (view);
+ gint x = event->x;
+ gint y = event->y;
+
+ if (drag_started)
+ {
+ if (event->state & GDK_BUTTON1_MASK)
+ {
+ gint diff_x = x - priv->prev_x;
+ gint diff_y = y - priv->prev_y;
+
+ priv->x -= diff_x;
+ priv->y -= diff_y;
+
+ gdk_window_scroll (widget->window, diff_x, diff_y);
+
+ g_object_notify (G_OBJECT (view), "x");
+ g_object_notify (G_OBJECT (view), "y");
+ }
+ else if (event->state & GDK_BUTTON2_MASK)
+ {
+ gint diff = priv->prev_y - y;
+ gint i;
+
+ if (diff < 0)
+ {
+ for (i=0;i>diff;i--)
+ {
+ priv->scale /= 1.006;
+ }
+ }
+ else
+ {
+ for (i=0;i<diff;i++)
+ {
+ priv->scale *= 1.006;
+ }
+ }
+
+ priv->x = (priv->start_buf_x - priv->screen_x / priv->scale) * priv->scale;
+ priv->y = (priv->start_buf_y - priv->screen_y / priv->scale) * priv->scale;
+
+ gtk_widget_queue_draw (GTK_WIDGET (view));
+
+ g_object_notify (G_OBJECT (view), "x");
+ g_object_notify (G_OBJECT (view), "y");
+ g_object_notify (G_OBJECT (view), "scale");
+ }
+
+ priv->prev_x = x;
+ priv->prev_y = y;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GeglView *view = GEGL_VIEW (widget);
+ GeglViewPrivate *priv = GEGL_VIEW_GET_PRIVATE (view);
+ GdkRectangle *rectangles;
+ gint count;
+ gint i;
+
+ if (! priv->node)
+ return FALSE;
+
+ gdk_region_get_rectangles (event->region, &rectangles, &count);
+
+ for (i=0; i<count; i++)
+ {
+ GeglRectangle roi;
+ guchar *buf;
+
+ roi.x = priv->x + rectangles[i].x;
+ roi.y = priv->y + rectangles[i].y;
+ roi.width = rectangles[i].width;
+ roi.height = rectangles[i].height;
+
+ buf = g_malloc ((roi.width) * (roi.height) * 3);
+
+ gegl_node_blit (priv->node,
+ priv->scale,
+ &roi,
+ babl_format ("R'G'B' u8"),
+ (gpointer)buf,
+ GEGL_AUTO_ROWSTRIDE,
+ GEGL_BLIT_CACHE|(priv->block?0:GEGL_BLIT_DIRTY));
+
+ gdk_draw_rgb_image (widget->window,
+ widget->style->black_gc,
+ rectangles[i].x, rectangles[i].y,
+ rectangles[i].width, rectangles[i].height,
+ GDK_RGB_DITHER_NONE,
+ buf, roi.width * 3);
+ g_free (buf);
+ }
+
+ g_free (rectangles);
+
+ gegl_view_repaint (view);
+
+ return FALSE;
+}
+
+static gboolean
+task_monitor (GeglView *view)
+{
+ GeglViewPrivate *priv = GEGL_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_view_repaint (GeglView *view)
+{
+ GtkWidget *widget = GTK_WIDGET (view);
+ GeglViewPrivate *priv = GEGL_VIEW_GET_PRIVATE (view);
+ GeglRectangle roi = { priv->x / priv->scale, priv->y / priv->scale,
+ ceil(widget->allocation.width / priv->scale+1),
+ ceil(widget->allocation.height / priv->scale+1) };
+
+#if 0
+ /* forget all already queued repaints */
+ gegl_cache_dequeue (gegl_node_get_cache (priv->node), NULL);
+ /* then enqueue our selves */
+ gegl_cache_enqueue (gegl_node_get_cache (priv->node), roi);
+#endif
+
+ 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);
+}
+
+GeglProcessor *
+gegl_view_get_processor (GeglView *self)
+{
+ GeglViewPrivate *priv = GEGL_VIEW_GET_PRIVATE (self);
+ return priv->processor;
+}
Added: trunk/examples/util/gegl-view.h
==============================================================================
--- (empty file)
+++ trunk/examples/util/gegl-view.h Tue Jan 6 15:36:42 2009
@@ -0,0 +1,51 @@
+/* This file is part of GEGL editor -- a gtk frontend for GEGL
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (C) 2003, 2004, 2006 Ãyvind KolÃs
+ */
+
+#ifndef __GEGL_VIEW_H__
+#define __GEGL_VIEW_H__
+
+G_BEGIN_DECLS
+
+#define GEGL_TYPE_VIEW (gegl_view_get_type ())
+#define GEGL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEGL_TYPE_VIEW, GeglView))
+#define GEGL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEGL_TYPE_VIEW, GeglViewClass))
+#define GEGL_IS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEGL_TYPE_VIEW))
+#define GEGL_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEGL_TYPE_VIEW))
+#define GEGL_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEGL_TYPE_VIEW, GeglViewClass))
+
+typedef struct _GeglView GeglView;
+typedef struct _GeglViewClass GeglViewClass;
+
+struct _GeglView
+{
+ GtkDrawingArea parent_instance;
+
+};
+
+struct _GeglViewClass
+{
+ GtkDrawingAreaClass parent_class;
+};
+
+GType gegl_view_get_type (void) G_GNUC_CONST;
+void gegl_view_repaint (GeglView *view);
+GeglProcessor * gegl_view_get_processor (GeglView *view);
+
+G_END_DECLS
+
+#endif /* __GEGL_VIEW_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]