[gegl-gtk] operations: Use GeglGtkView widget in display operation
- From: Jon Nordby <jonnor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl-gtk] operations: Use GeglGtkView widget in display operation
- Date: Fri, 19 Aug 2011 19:30:38 +0000 (UTC)
commit c93f2eb12b28cb24fb269dfe80eeb3f75e2cdb50
Author: Jon Nordby <jononor gmail com>
Date: Mon Jun 27 02:09:16 2011 +0200
operations: Use GeglGtkView widget in display operation
Reduces code duplication.
Currently the operation does not spin the GTK+ main
loop. This needs to be fixed.
Also adds an example for how to use the operation.
examples/.gitignore | 1 +
examples/gegl-gtk-display-op.c | 60 +++++++++++++++
gegl-gtk/Makefile.am | 2 +-
operations/Makefile.am | 12 ++--
operations/gegl-gtk-display.c | 159 ++++++++++------------------------------
5 files changed, 108 insertions(+), 126 deletions(-)
---
diff --git a/examples/.gitignore b/examples/.gitignore
index 727dec4..264e3fe 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -1,2 +1,3 @@
gegl-gtk-paint
gegl-gtk-basic
+gegl-gtk-display-op
diff --git a/examples/gegl-gtk-display-op.c b/examples/gegl-gtk-display-op.c
new file mode 100644
index 0000000..f0bba61
--- /dev/null
+++ b/examples/gegl-gtk-display-op.c
@@ -0,0 +1,60 @@
+/* This file is part of GEGL-GTK
+ *
+ * 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) 2011 Jon Nordby <jononor gmail com>
+ */
+
+#include <string.h>
+#include <glib.h>
+#include <gegl.h>
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+ GeglNode *graph = NULL;
+ GeglNode *node = NULL;
+ GeglNode *display = NULL;
+
+ g_thread_init (NULL);
+ gegl_init (&argc, &argv);
+
+ if (argc != 2) {
+ g_print ("Usage: %s <FILENAME>\n", argv[0]);
+ exit(1);
+ }
+
+ /* Build graph that loads an image */
+ graph = gegl_node_new ();
+ node = gegl_node_new_child (graph,
+ "operation", "gegl:load",
+ "path", argv[1], NULL);
+ display = gegl_node_new_child (graph,
+ "operation", "gegl-gtk2:display", NULL);
+ gegl_node_link_many (node, display, NULL);
+
+ gegl_node_process (display);
+
+ /* FIXME: operation must spin the gtk mainloop itself */
+ while (gtk_events_pending ())
+ gtk_main_iteration ();
+
+ sleep (2);
+
+ /* Cleanup */
+ g_object_unref (graph);
+ gegl_exit ();
+ return 0;
+}
diff --git a/gegl-gtk/Makefile.am b/gegl-gtk/Makefile.am
index 7578d0b..df6a5dd 100644
--- a/gegl-gtk/Makefile.am
+++ b/gegl-gtk/Makefile.am
@@ -9,7 +9,7 @@ gegl_gtk_include_HEADERS = $(headers)
gegl_gtk_SOURCES = $(headers) $(sources)
gegl_gtk_LIBADD = $(GTK_LIBS) $(GEGL_LIBS)
-gegl_gtk_CFLAGS = $(INCLUDES)
+gegl_gtk_CFLAGS = $(INCLUDES) $(CFLAGS)
if HAVE_GTK2
lib_LTLIBRARIES = libgegl-gtk2-0.1.la
diff --git a/operations/Makefile.am b/operations/Makefile.am
index 985baa5..ecc5b96 100644
--- a/operations/Makefile.am
+++ b/operations/Makefile.am
@@ -1,9 +1,10 @@
ext_dir = $(GEGL_PLUGINS_DIR)
+libgeglgtk = $(top_builddir)/gegl-gtk/libgegl-gtk$(GEGL_GTK_GTK_VERSION)-$(GEGL_GTK_API_VERSION).la
-LIBS = $(GTK_LIBS) $(GEGL_LIBS)
-CFLAGS = $(GTK_CFLAGS) $(GEGL_CFLAGS)
-LDFLAGS = -avoid-version -export-dynamic -module
+op_LIBS = $(GTK_LIBS) $(GEGL_LIBS) $(libgeglgtk)
+op_CFLAGS = $(GTK_CFLAGS) $(GEGL_CFLAGS)
+op_LDFLAGS = -avoid-version -export-dynamic -module
CFILES = $(wildcard $(srcdir)/*.c)
plugins = $(subst gegl-gtk-,gegl-gtk GEGL_GTK_GTK_VERSION@-, $(subst $(srcdir)/,,$(CFILES:.c=.la)))
@@ -20,9 +21,8 @@ gegl_lt_ccld_v_0 = @echo " CCLD " $@;
all-local: $(plugins)
gegl-gtk GEGL_GTK_GTK_VERSION@-%.la: gegl-gtk-%.c
- $(gegl_lt_cc_v) $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(DEFS) -I. -I$(top_builddir) -I$(srcdir) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $ lo $<
- $(gegl_lt_ccld_v) $(LIBTOOL) --quiet --tag=CC --mode=link $(CC) $(AM_LDFLAGS) $(LDFLAGS) $(CFLAGS) -o $@ -rpath $(ext_dir) $ lo $(LIBS) $(MATH_LIB)
-
+ $(gegl_lt_cc_v) $(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(DEFS) -I. -I$(top_builddir) -I$(top_srcdir)/gegl-gtk -I$(srcdir) $(AM_CPPFLAGS) $(CPPFLAGS) $(op_CFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o $ lo $<
+ $(gegl_lt_ccld_v) $(LIBTOOL) --quiet --tag=CC --mode=link $(CC) $(AM_LDFLAGS) $(op_LDFLAGS) $(op_CFLAGS) $(CFLAGS) -o $@ -rpath $(ext_dir) $ lo $(op_LIBS) $(MATH_LIB)
clean-local:
rm -f *.la
diff --git a/operations/gegl-gtk-display.c b/operations/gegl-gtk-display.c
index 5019c65..cf4804d 100644
--- a/operations/gegl-gtk-display.c
+++ b/operations/gegl-gtk-display.c
@@ -32,75 +32,22 @@ gegl_chant_string (window_title, _("Window Title"), "",
#include <gegl.h>
#include <gegl-chant.h>
+
#include <gtk/gtk.h>
+#include <gegl-gtk.h>
typedef struct
{
GtkWidget *window;
- GtkWidget *drawing_area;
+ GtkWidget *view_widget;
+ GeglNode *node;
+ GeglNode *input;
gint width;
gint height;
- guchar *buf;
} Priv;
-
-static void
-draw_implementation (Priv *priv, cairo_t *cr)
-{
- cairo_surface_t *surface = NULL;
-
- if (!priv->buf)
- return;
-
- surface = cairo_image_surface_create_for_data (priv->buf,
- CAIRO_FORMAT_ARGB32,
- priv->width, priv->height,
- priv->width*4);
-
- cairo_set_source_surface (cr, surface, 0.0, 0.0);
- cairo_paint (cr);
-
- cairo_surface_finish (surface);
-}
-
-#ifdef HAVE_GTK2
-static gboolean
-expose_event (GtkWidget *widget, GdkEventExpose * event, gpointer user_data)
-{
- GeglChantO *o = GEGL_CHANT_PROPERTIES (g_object_get_data (G_OBJECT (widget), "op"));
- Priv *priv = (Priv*)o->chant_data;
- cairo_t *cr = gdk_cairo_create (widget->window);
-
- if (event->area.x + event->area.width > priv->width)
- event->area.width = priv->width - event->area.x;
- if (event->area.y + event->area.height > priv->height)
- event->area.height = priv->height - event->area.y;
-
- cairo_rectangle (cr, event->area.x, event->area.y,
- event->area.width, event->area.height);
- cairo_clip (cr);
-
- draw_implementation (priv, cr);
- cairo_destroy (cr);
-
- return TRUE;
-}
-#endif
-
-#ifdef HAVE_GTK3
-static gboolean
-draw (GtkWidget * widget, cairo_t *cr, gpointer user_data)
-{
- GeglChantO *o = GEGL_CHANT_PROPERTIES (g_object_get_data (G_OBJECT (widget), "op"));
- Priv *priv = (Priv*)o->chant_data;
-
- draw_implementation (priv, cr);
-
- return TRUE;
-}
-#endif
-
-static Priv *init_priv (GeglOperation *operation)
+static Priv *
+init_priv (GeglOperation *operation)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
@@ -112,90 +59,69 @@ static Priv *init_priv (GeglOperation *operation)
gtk_init (0, 0);
priv->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- priv->drawing_area = gtk_drawing_area_new ();
- gtk_container_add (GTK_CONTAINER (priv->window), priv->drawing_area);
+ priv->view_widget = g_object_new (GEGL_GTK_TYPE_VIEW, NULL);
+ gtk_container_add (GTK_CONTAINER (priv->window), priv->view_widget);
priv->width = -1;
priv->height = -1;
- gtk_widget_set_size_request (priv->drawing_area, priv->width, priv->height);
+ gtk_widget_set_size_request (priv->view_widget, priv->width, priv->height);
gtk_window_set_title (GTK_WINDOW (priv->window), o->window_title);
-#ifdef HAVE_GTK2
- g_signal_connect (G_OBJECT (priv->drawing_area), "expose_event",
- G_CALLBACK (expose_event), priv);
-#endif
-
-#ifdef HAVE_GTK3
- g_signal_connect (G_OBJECT (priv->drawing_area), "draw",
- G_CALLBACK (draw), priv);
-#endif
-
- g_object_set_data (G_OBJECT (priv->drawing_area), "op", operation);
+ priv->node = NULL;
+ priv->input = NULL;
gtk_widget_show_all (priv->window);
-
- priv->buf = NULL;
}
return (Priv*)(o->chant_data);
}
-static gboolean
-process (GeglOperation *operation,
- GeglBuffer *input,
- const GeglRectangle *result)
+static void
+set_window_attributes (GeglOperation *operation, const GeglRectangle *result)
{
GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
Priv *priv = init_priv (operation);
- GeglBuffer *source = NULL;
- Babl *format = NULL;
-
- g_assert (input);
if (priv->width != result->width ||
priv->height != result->height)
{
priv->width = result->width ;
priv->height = result->height;
- gtk_widget_set_size_request (priv->drawing_area, priv->width, priv->height);
-
- if (priv->buf)
- g_free (priv->buf);
- priv->buf = g_malloc (priv->width * priv->height * 4);
+ gtk_widget_set_size_request (priv->view_widget, priv->width, priv->height);
}
-
- source = gegl_buffer_create_sub_buffer (input, result);
-
- format = babl_format_new (babl_model ("RGBA"), babl_type ("u8"),
- babl_component ("B"),
- babl_component ("G"),
- babl_component ("R"),
- babl_component ("A"),
- NULL);
- gegl_buffer_get (source, 1.0, NULL, format,
- priv->buf, GEGL_AUTO_ROWSTRIDE);
- gtk_widget_queue_draw (priv->drawing_area);
+
if (priv->window)
{
gtk_window_resize (GTK_WINDOW (priv->window), priv->width, priv->height);
- if (o->window_title[0]!='\0')
+ if (o->window_title && o->window_title[0]!='\0')
{
gtk_window_set_title (GTK_WINDOW (priv->window), o->window_title);
}
else
{
gtk_window_set_title (GTK_WINDOW (priv->window),
- gegl_node_get_debug_name (gegl_node_get_producer(operation->node, "input", NULL))
- );
+ gegl_node_get_debug_name (gegl_node_get_producer(operation->node, "input", NULL))
+ );
}
+ }
+}
- while (gtk_events_pending ())
- {
- gtk_main_iteration ();
- }
- }
- g_object_unref (source);
+/* Create an input proxy, and initial display operation, and link together.
+ * These will be passed control when process is called later. */
+static void
+attach (GeglOperation *operation)
+{
+ Priv *priv = init_priv (operation);
- return TRUE;
+ g_assert (!priv->input);
+ g_assert (!priv->node);
+
+ priv->input = gegl_node_get_input_proxy (operation->node, "input");
+ priv->node = gegl_node_new_child (operation->node,
+ "operation", "gegl:nop",
+ NULL);
+
+ gegl_node_link (priv->input, priv->node);
+ g_object_set (G_OBJECT (priv->view_widget), "node", priv->node, NULL);
}
static void
@@ -207,8 +133,6 @@ dispose (GObject *object)
if (priv)
{
gtk_widget_destroy (priv->window);
- if (priv->buf)
- g_free (priv->buf);
g_free (priv);
o->chant_data = NULL;
}
@@ -220,13 +144,10 @@ dispose (GObject *object)
static void
gegl_chant_class_init (GeglChantClass *klass)
{
- GeglOperationClass *operation_class;
- GeglOperationSinkClass *sink_class;
-
- operation_class = GEGL_OPERATION_CLASS (klass);
- sink_class = GEGL_OPERATION_SINK_CLASS (klass);
+ GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
+ GeglOperationSinkClass *sink_class = GEGL_OPERATION_SINK_CLASS (klass);
- sink_class->process = process;
+ operation_class->attach = attach;
G_OBJECT_CLASS (klass)->dispose = dispose;
#ifdef HAVE_GTK2
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]