[gnome-photos/wip/rishi/imageview: 7/7] image-container: foo



commit 3644403a8a3dd19a7a9bf196add705d097a64be3
Author: Debarshi Ray <debarshir gnome org>
Date:   Wed Feb 3 14:37:18 2016 +0100

    image-container: foo

 src/photos-image-container.c |  113 +++++++++++++++++++++++++++++++++++++-----
 1 files changed, 101 insertions(+), 12 deletions(-)
---
diff --git a/src/photos-image-container.c b/src/photos-image-container.c
index 45cc1ce..af0eca5 100644
--- a/src/photos-image-container.c
+++ b/src/photos-image-container.c
@@ -35,10 +35,12 @@ struct _PhotosImageContainer
   GeglNode *buffer_source;
   GeglNode *graph;
   GeglNode *node;
+  GeglRectangle bbox;
   GtkWidget *stack;
   GtkWidget *view;
   cairo_region_t *bbox_region;
   cairo_region_t *region;
+  guint computed_id;
 };
 
 struct _PhotosImageContainerClass
@@ -72,19 +74,54 @@ photos_image_container_notify_transition_running (GtkStack *stack, GParamSpec *p
 }
 
 
-static gboolean
-photos_image_container_computed_idle (gpointer user_data)
+static void
+photos_image_container_crossfade (PhotosImageContainer *self)
 {
-  PhotosImageContainer *self = PHOTOS_IMAGE_CONTAINER (user_data);
   const Babl *format;
   GeglBuffer *buffer;
   GeglBuffer *buffer_orig;
   GtkWidget *view;
 
-  g_return_val_if_fail (self->buffer_source != NULL, G_SOURCE_REMOVE);
+  view = photos_image_view_new_from_node (self->buffer_source);
+  gtk_container_add (GTK_CONTAINER (self->stack), view);
+  gtk_widget_show (view);
+  gtk_stack_set_visible_child (GTK_STACK (self->stack), view);
+
+  g_clear_object (&self->graph);
+  g_signal_handlers_block_by_func (self->node, photos_image_container_computed, self);
+
+  format = babl_format ("cairo-ARGB32");
+  buffer_orig = photos_utils_create_buffer_from_node (self->node, format);
+  buffer = gegl_buffer_dup (buffer_orig);
+  self->graph = gegl_node_new ();
+  self->buffer_source = gegl_node_new_child (self->graph,
+                                             "operation", "gegl:buffer-source",
+                                             "buffer", buffer,
+                                             NULL);
+  gegl_node_process (self->buffer_source);
+  photos_image_view_set_node (PHOTOS_IMAGE_VIEW (self->view), self->buffer_source);
+  gtk_stack_set_visible_child_full (GTK_STACK (self->stack), "view", GTK_STACK_TRANSITION_TYPE_CROSSFADE);
+  g_signal_connect (self->stack,
+                    "notify::transition-running",
+                    G_CALLBACK (photos_image_container_notify_transition_running),
+                    view);
+
+  g_signal_handlers_unblock_by_func (self->node, photos_image_container_computed, self);
+
+  g_object_unref (buffer);
+  g_object_unref (buffer_orig);
+}
+
+
+static void
+photos_image_container_rubber_band (PhotosImageContainer *self)
+{
+  const Babl *format;
+  GeglBuffer *buffer;
+  GeglBuffer *buffer_orig;
+  GtkWidget *view;
 
-  view = photos_image_view_new ();
-  photos_image_view_set_node (PHOTOS_IMAGE_VIEW (view), self->buffer_source);
+  view = photos_image_view_new_from_node (self->buffer_source);
   gtk_container_add (GTK_CONTAINER (self->stack), view);
   gtk_widget_show (view);
   gtk_stack_set_visible_child (GTK_STACK (self->stack), view);
@@ -108,11 +145,32 @@ photos_image_container_computed_idle (gpointer user_data)
                     G_CALLBACK (photos_image_container_notify_transition_running),
                     view);
 
-  gtk_widget_queue_draw (GTK_WIDGET (self));
   g_signal_handlers_unblock_by_func (self->node, photos_image_container_computed, self);
 
   g_object_unref (buffer);
   g_object_unref (buffer_orig);
+}
+
+
+static gboolean
+photos_image_container_computed_idle (gpointer user_data)
+{
+  PhotosImageContainer *self = PHOTOS_IMAGE_CONTAINER (user_data);
+  GeglRectangle bbox;
+
+  self->computed_id = 0;
+
+  g_return_val_if_fail (self->buffer_source != NULL, G_SOURCE_REMOVE);
+  g_return_val_if_fail (self->node != NULL, G_SOURCE_REMOVE);
+
+  g_message ("photos_image_computed_idle: %p", self->node);
+
+  bbox = gegl_node_get_bounding_box (self->node);
+  if (gegl_rectangle_equal (&self->bbox, &bbox))
+    photos_image_container_crossfade (self);
+  else
+    photos_image_container_rubber_band (self);
+
   return G_SOURCE_REMOVE;
 }
 
@@ -122,11 +180,27 @@ photos_image_container_computed (PhotosImageContainer *self, GeglRectangle *rect
 {
   cairo_status_t status;
 
+  if (self->computed_id != 0)
+    return;
+
   status = cairo_region_union_rectangle (self->region, (cairo_rectangle_int_t *) rect);
   g_assert_cmpint (status, ==, CAIRO_STATUS_SUCCESS);
 
+  g_message ("photos_image_container_computed: %p, %d %d %d %d",
+             self->node,
+             rect->x, rect->y, rect->width, rect->height);
+
   if (cairo_region_equal (self->bbox_region, self->region))
-    g_idle_add (photos_image_container_computed_idle, self);
+    self->computed_id = g_idle_add_full (G_PRIORITY_LOW, photos_image_container_computed_idle, self, NULL);
+}
+
+
+static void
+photos_image_container_invalidated (PhotosImageContainer *self, GeglRectangle *rect)
+{
+  g_message ("photos_image_container_invalidated: %p, %d %d %d %d",
+             self->node,
+             rect->x, rect->y, rect->width, rect->height);
 }
 
 
@@ -135,6 +209,12 @@ photos_image_container_dispose (GObject *object)
 {
   PhotosImageContainer *self = PHOTOS_IMAGE_CONTAINER (object);
 
+  if (self->computed_id != 0)
+    {
+      g_source_remove (self->computed_id);
+      self->computed_id = 0;
+    }
+
   g_clear_object (&self->graph);
   g_clear_object (&self->node);
 
@@ -284,9 +364,14 @@ photos_image_container_set_node (PhotosImageContainer *self, GeglNode *node)
     return;
 
   if (self->node != NULL)
-    g_signal_handlers_disconnect_by_func (self->node, photos_image_container_computed, self);
+    {
+      g_signal_handlers_disconnect_by_func (self->node, photos_image_container_computed, self);
+      g_signal_handlers_disconnect_by_func (self->node, photos_image_container_invalidated, self);
+    }
 
+  gegl_rectangle_set (&self->bbox, 0, 0, 0, 0);
   self->buffer_source = NULL;
+
   g_clear_object (&self->graph);
   g_clear_object (&self->node);
   g_clear_pointer (&self->bbox_region, (GDestroyNotify) cairo_region_destroy);
@@ -297,12 +382,11 @@ photos_image_container_set_node (PhotosImageContainer *self, GeglNode *node)
       const Babl *format;
       GeglBuffer *buffer;
       GeglBuffer *buffer_orig;
-      GeglRectangle bbox;
 
       g_object_ref (node);
 
-      bbox = gegl_node_get_bounding_box (node);
-      self->bbox_region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &bbox);
+      self->bbox = gegl_node_get_bounding_box (node);
+      self->bbox_region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &self->bbox);
       self->region = cairo_region_create ();
 
       format = babl_format ("cairo-ARGB32");
@@ -320,6 +404,11 @@ photos_image_container_set_node (PhotosImageContainer *self, GeglNode *node)
                                G_CALLBACK (photos_image_container_computed),
                                self,
                                G_CONNECT_SWAPPED);
+      g_signal_connect_object (node,
+                               "invalidated",
+                               G_CALLBACK (photos_image_container_invalidated),
+                               self,
+                               G_CONNECT_SWAPPED);
 
       g_object_unref (buffer);
       g_object_unref (buffer_orig);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]