[gimp] app: in GimpLineArt, use "invalidate-preview" signal of input viewable



commit ef9b1f6694b9f44f6b55fabfb5898a4b35c5b88f
Author: Ell <ell_se yahoo com>
Date:   Thu Dec 27 17:07:46 2018 -0500

    app: in GimpLineArt, use "invalidate-preview" signal of input viewable
    
    In GimpLineArt, use the "invalidate-preview" signal of the input
    viewable, instead of its "painted" or "rendered" signals, for
    asynchronously computing the line art.  Subsequently, remove the
    aforementioned signals from GimpDrawable and GimpProjection,
    respectively.  This simplifies the code, and reduces the number of
    signals.

 app/core/gimpdrawable.c   |  30 -------------
 app/core/gimpdrawable.h   |   1 -
 app/core/gimplineart.c    | 112 ++++++++++++++++++++--------------------------
 app/core/gimpprojection.c |  11 -----
 app/core/gimpprojection.h |  13 +++---
 5 files changed, 54 insertions(+), 113 deletions(-)
---
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 2e85d0777f..46d418b5cf 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -66,7 +66,6 @@
 enum
 {
   UPDATE,
-  PAINTED,
   ALPHA_CHANGED,
   LAST_SIGNAL
 };
@@ -220,16 +219,6 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
   GimpFilterClass   *filter_class      = GIMP_FILTER_CLASS (klass);
   GimpItemClass     *item_class        = GIMP_ITEM_CLASS (klass);
 
-  /**
-   * GimpDrawable::update:
-   * @drawable: the object which received the signal.
-   * @x:
-   * @y:
-   * @width:
-   * @height:
-   *
-   * This signal is emitted when a region of the drawable is updated.
-   **/
   gimp_drawable_signals[UPDATE] =
     g_signal_new ("update",
                   G_TYPE_FROM_CLASS (klass),
@@ -243,24 +232,6 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
                   G_TYPE_INT,
                   G_TYPE_INT);
 
-  /**
-   * GimpDrawable::painted:
-   * @drawable: the object which received the signal.
-   *
-   * This signal is emitted when the drawable has been painted. Unlike
-   * the "update" signal, it will be emitted once for a single paint
-   * event (whereas several "update" signals could be emitted
-   * sequentially for various regions of the drawable).
-   **/
-  gimp_drawable_signals[PAINTED] =
-    g_signal_new ("painted",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (GimpDrawableClass, painted),
-                  NULL, NULL,
-                  gimp_marshal_VOID__VOID,
-                  G_TYPE_NONE, 0);
-
   gimp_drawable_signals[ALPHA_CHANGED] =
     g_signal_new ("alpha-changed",
                   G_TYPE_FROM_CLASS (klass),
@@ -1044,7 +1015,6 @@ gimp_drawable_update (GimpDrawable *drawable,
     {
       g_signal_emit (drawable, gimp_drawable_signals[UPDATE], 0,
                      x, y, width, height);
-      g_signal_emit (drawable, gimp_drawable_signals[PAINTED], 0);
     }
   else
     {
diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h
index 58cf9281c6..5a59f33c5c 100644
--- a/app/core/gimpdrawable.h
+++ b/app/core/gimpdrawable.h
@@ -50,7 +50,6 @@ struct _GimpDrawableClass
                                            gint                  y,
                                            gint                  width,
                                            gint                  height);
-  void          (* painted)               (GimpDrawable         *drawable);
   void          (* alpha_changed)         (GimpDrawable         *drawable);
 
   /*  virtual functions  */
diff --git a/app/core/gimplineart.c b/app/core/gimplineart.c
index 9bf15e438a..c1ada880f7 100644
--- a/app/core/gimplineart.c
+++ b/app/core/gimplineart.c
@@ -28,6 +28,7 @@
 #include "core-types.h"
 
 #include "gimp-parallel.h"
+#include "gimp-priorities.h"
 #include "gimp-utils.h" /* GIMP_TIMER */
 #include "gimpasync.h"
 #include "gimpcancelable.h"
@@ -36,6 +37,7 @@
 #include "gimplineart.h"
 #include "gimppickable.h"
 #include "gimpprojection.h"
+#include "gimpviewable.h"
 #include "gimpwaitable.h"
 
 #include "gimp-intl.h"
@@ -59,6 +61,8 @@ struct _GimpLineArtPrivate
 
   GimpAsync    *async;
 
+  gint          idle_id;
+
   GimpPickable *input;
   GeglBuffer   *closed;
   gfloat       *distmap;
@@ -156,9 +160,8 @@ static LineArtResult * line_art_result_new                     (GeglBuffer
                                                                 gfloat                 *distmap);
 static void            line_art_result_free                    (LineArtResult          *result);
 
-static void            gimp_line_art_projection_rendered       (GimpProjection         *proj,
-                                                                GimpLineArt            *line_art);
-static void            gimp_line_art_drawable_painted          (GimpDrawable           *drawable,
+static gboolean        gimp_line_art_idle                      (GimpLineArt            *line_art);
+static void            gimp_line_art_input_invalidate_preview  (GimpViewable           *viewable,
                                                                 GimpLineArt            *line_art);
 
 
@@ -330,28 +333,9 @@ gimp_line_art_finalize (GObject *object)
 {
   GimpLineArt *line_art = GIMP_LINE_ART (object);
 
-  if (line_art->priv->input)
-    {
-      if (GIMP_IS_IMAGE (line_art->priv->input))
-        g_signal_handlers_disconnect_by_data (gimp_image_get_projection (GIMP_IMAGE (line_art->priv->input)),
-                                              line_art);
-      else
-        g_signal_handlers_disconnect_by_data (line_art->priv->input,
-                                              line_art);
-    }
-  if (line_art->priv->async)
-    {
-      /* we cancel the async, but don't wait for it to finish, since
-       * it can't actually be interrupted.  instead
-       * gimp_bucket_fill_compute_line_art_cb() bails if the async has
-       * been canceled, to avoid accessing the dead tool.
-       */
-      gimp_cancelable_cancel (GIMP_CANCELABLE (line_art->priv->async));
-      g_clear_object (&line_art->priv->async);
-    }
+  line_art->priv->frozen = FALSE;
 
-  g_clear_object (&line_art->priv->closed);
-  g_clear_pointer (&line_art->priv->distmap, g_free);
+  gimp_line_art_set_input (line_art, NULL);
 }
 
 static void
@@ -435,31 +419,20 @@ void
 gimp_line_art_set_input (GimpLineArt  *line_art,
                          GimpPickable *pickable)
 {
+  g_return_if_fail (pickable == NULL || GIMP_IS_VIEWABLE (pickable));
+
   if (line_art->priv->input)
-    {
-      if (GIMP_IS_IMAGE (line_art->priv->input))
-        g_signal_handlers_disconnect_by_data (gimp_image_get_projection (GIMP_IMAGE (line_art->priv->input)),
-                                              line_art);
-      else
-        g_signal_handlers_disconnect_by_data (line_art->priv->input,
-                                              line_art);
-    }
+    g_signal_handlers_disconnect_by_data (line_art->priv->input, line_art);
 
   line_art->priv->input = pickable;
 
   gimp_line_art_compute (line_art);
+
   if (pickable)
     {
-      if (GIMP_IS_IMAGE (pickable))
-        g_signal_connect (gimp_image_get_projection (GIMP_IMAGE (pickable)), "rendered",
-                          G_CALLBACK (gimp_line_art_projection_rendered),
-                          line_art);
-      else if (GIMP_IS_DRAWABLE (pickable))
-        g_signal_connect (pickable, "painted",
-                          G_CALLBACK (gimp_line_art_drawable_painted),
-                          line_art);
-      else
-        g_return_if_reached ();
+      g_signal_connect (pickable, "invalidate-preview",
+                        G_CALLBACK (gimp_line_art_input_invalidate_preview),
+                        line_art);
     }
 }
 
@@ -523,10 +496,20 @@ gimp_line_art_compute (GimpLineArt *line_art)
 
   if (line_art->priv->async)
     {
+      /* we cancel the async, but don't wait for it to finish, since
+       * it can't actually be interrupted.  instead gimp_line_art_compute_cb()
+       * bails if the async has been canceled, to avoid accessing the line art.
+       */
       gimp_cancelable_cancel (GIMP_CANCELABLE (line_art->priv->async));
       g_clear_object (&line_art->priv->async);
     }
 
+  if (line_art->priv->idle_id)
+    {
+      g_source_remove (line_art->priv->idle_id);
+      line_art->priv->idle_id = 0;
+    }
+
   g_clear_object (&line_art->priv->closed);
   g_clear_pointer (&line_art->priv->distmap, g_free);
 
@@ -536,23 +519,15 @@ gimp_line_art_compute (GimpLineArt *line_art)
        * may trigger this signal handler, and will leak a line art (as
        * line_art->priv->async has not been set yet).
        */
-      if (GIMP_IS_IMAGE (line_art->priv->input))
-        g_signal_handlers_block_by_func (gimp_image_get_projection (GIMP_IMAGE (line_art->priv->input)),
-                                         G_CALLBACK (gimp_line_art_projection_rendered),
-                                         line_art);
-      else
-        g_signal_handlers_block_by_func (line_art->priv->input,
-                                         G_CALLBACK (gimp_line_art_drawable_painted),
-                                         line_art);
+      g_signal_handlers_block_by_func (
+        line_art->priv->input,
+        G_CALLBACK (gimp_line_art_input_invalidate_preview),
+        line_art);
       line_art->priv->async = gimp_line_art_prepare_async (line_art, +1);
-      if (GIMP_IS_IMAGE (line_art->priv->input))
-        g_signal_handlers_unblock_by_func (gimp_image_get_projection (GIMP_IMAGE (line_art->priv->input)),
-                                           G_CALLBACK (gimp_line_art_projection_rendered),
-                                           line_art);
-      else
-        g_signal_handlers_unblock_by_func (line_art->priv->input,
-                                           G_CALLBACK (gimp_line_art_drawable_painted),
-                                           line_art);
+      g_signal_handlers_unblock_by_func (
+        line_art->priv->input,
+        G_CALLBACK (gimp_line_art_input_invalidate_preview),
+        line_art);
 
       gimp_async_add_callback_for_object (line_art->priv->async,
                                           (GimpAsyncCallback) gimp_line_art_compute_cb,
@@ -750,18 +725,27 @@ line_art_result_free (LineArtResult *data)
   g_slice_free (LineArtResult, data);
 }
 
-static void
-gimp_line_art_projection_rendered (GimpProjection *proj,
-                                   GimpLineArt    *line_art)
+static gboolean
+gimp_line_art_idle (GimpLineArt *line_art)
 {
+  line_art->priv->idle_id = 0;
+
   gimp_line_art_compute (line_art);
+
+  return G_SOURCE_REMOVE;
 }
 
 static void
-gimp_line_art_drawable_painted (GimpDrawable *drawable,
-                                GimpLineArt  *line_art)
+gimp_line_art_input_invalidate_preview (GimpViewable *viewable,
+                                        GimpLineArt  *line_art)
 {
-  gimp_line_art_compute (line_art);
+  if (! line_art->priv->idle_id)
+    {
+      line_art->priv->idle_id = g_idle_add_full (
+        GIMP_PRIORITY_VIEWABLE_IDLE,
+        (GSourceFunc) gimp_line_art_idle,
+        line_art, NULL);
+    }
 }
 
 /* All actual computation functions. */
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index cb912a4b88..ae1e8ca5ae 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -81,7 +81,6 @@ static gdouble GIMP_PROJECTION_CHUNK_TIME = 0.0666;
 enum
 {
   UPDATE,
-  RENDERED,
   LAST_SIGNAL
 };
 
@@ -259,15 +258,6 @@ gimp_projection_class_init (GimpProjectionClass *klass)
                   G_TYPE_INT,
                   G_TYPE_INT);
 
-  projection_signals[RENDERED] =
-    g_signal_new ("rendered",
-                  G_TYPE_FROM_CLASS (klass),
-                  G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (GimpProjectionClass, rendered),
-                  NULL, NULL,
-                  gimp_marshal_VOID__VOID,
-                  G_TYPE_NONE, 0);
-
   object_class->finalize         = gimp_projection_finalize;
   object_class->set_property     = gimp_projection_set_property;
   object_class->get_property     = gimp_projection_get_property;
@@ -852,7 +842,6 @@ gimp_projection_chunk_render_stop (GimpProjection *proj)
 
   g_source_remove (proj->priv->chunk_render.idle_id);
   proj->priv->chunk_render.idle_id = 0;
-  g_signal_emit (proj, projection_signals[RENDERED], 0);
 }
 
 static gboolean
diff --git a/app/core/gimpprojection.h b/app/core/gimpprojection.h
index 36d76d076c..8c9baf69e6 100644
--- a/app/core/gimpprojection.h
+++ b/app/core/gimpprojection.h
@@ -44,13 +44,12 @@ struct _GimpProjectionClass
 {
   GimpObjectClass  parent_class;
 
-  void (* update)   (GimpProjection *proj,
-                     gboolean        now,
-                     gint            x,
-                     gint            y,
-                     gint            width,
-                     gint            height);
-  void (* rendered) (GimpProjection *proj);
+  void (* update) (GimpProjection *proj,
+                   gboolean        now,
+                   gint            x,
+                   gint            y,
+                   gint            width,
+                   gint            height);
 };
 
 


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