[gimp] app: move GimpDrawable's FS to gimpdrawable-floating-selection.[ch]



commit 81fd3e9c3f56e3ee9bfc53fb688cc936893feb61
Author: Michael Natterer <mitch gimp org>
Date:   Thu May 19 17:38:55 2016 +0200

    app: move GimpDrawable's FS to gimpdrawable-floating-selection.[ch]
    
    and refactor it a bit to have separate functions for adding, removing
    and updating the FS' drawable filter. Should be a lot more
    understandable now.

 app/core/Makefile.am                       |    2 +
 app/core/gimpdrawable-floating-selection.c |  391 ++++++++++++++++++++++++++++
 app/core/gimpdrawable-floating-selection.h |   31 +++
 app/core/gimpdrawable.c                    |  342 +------------------------
 app/core/gimpdrawable.h                    |    7 -
 app/core/gimpfloatingselundo.c             |    1 +
 app/core/gimpimage.c                       |    1 +
 app/core/gimplayer.c                       |    1 +
 po/POTFILES.in                             |    1 +
 9 files changed, 431 insertions(+), 346 deletions(-)
---
diff --git a/app/core/Makefile.am b/app/core/Makefile.am
index 6b1edf8..1be6439 100644
--- a/app/core/Makefile.am
+++ b/app/core/Makefile.am
@@ -145,6 +145,8 @@ libappcore_a_sources = \
        gimpdrawable-fill.h                     \
        gimpdrawable-filters.c                  \
        gimpdrawable-filters.h                  \
+       gimpdrawable-floating-selection.c       \
+       gimpdrawable-floating-selection.h       \
        gimpdrawable-foreground-extract.c       \
        gimpdrawable-foreground-extract.h       \
        gimpdrawable-histogram.c                \
diff --git a/app/core/gimpdrawable-floating-selection.c b/app/core/gimpdrawable-floating-selection.c
new file mode 100644
index 0000000..b33a350
--- /dev/null
+++ b/app/core/gimpdrawable-floating-selection.c
@@ -0,0 +1,391 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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/>.
+ */
+
+#include "config.h"
+
+#include <cairo.h>
+#include <gegl.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "libgimpbase/gimpbase.h"
+
+#include "core-types.h"
+
+#include "gegl/gimpapplicator.h"
+
+#include "gimpchannel.h"
+#include "gimpdrawable-floating-selection.h"
+#include "gimpdrawable-filters.h"
+#include "gimpdrawable-private.h"
+#include "gimpimage.h"
+#include "gimplayer.h"
+
+#include "gimp-log.h"
+
+#include "gimp-intl.h"
+
+
+/*  local function prototypes  */
+
+static void    gimp_drawable_remove_fs_filter   (GimpDrawable      *drawable);
+static void    gimp_drawable_sync_fs_filter     (GimpDrawable      *drawable);
+
+static void    gimp_drawable_fs_notify          (GimpLayer         *fs,
+                                                 const GParamSpec  *pspec,
+                                                 GimpDrawable      *drawable);
+static void    gimp_drawable_fs_affect_changed  (GimpImage         *image,
+                                                 GimpChannelType    channel,
+                                                 GimpDrawable      *drawable);
+static void    gimp_drawable_fs_mask_changed    (GimpImage         *image,
+                                                 GimpDrawable      *drawable);
+static void    gimp_drawable_fs_update          (GimpLayer         *fs,
+                                                 gint               x,
+                                                 gint               y,
+                                                 gint               width,
+                                                 gint               height,
+                                                 GimpDrawable      *drawable);
+
+
+/*  public functions  */
+
+GimpLayer *
+gimp_drawable_get_floating_sel (GimpDrawable *drawable)
+{
+  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
+
+  return drawable->private->floating_selection;
+}
+
+void
+gimp_drawable_attach_floating_sel (GimpDrawable *drawable,
+                                   GimpLayer    *fs)
+{
+  GimpImage *image;
+
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
+  g_return_if_fail (gimp_drawable_get_floating_sel (drawable) == NULL);
+  g_return_if_fail (GIMP_IS_LAYER (fs));
+
+  GIMP_LOG (FLOATING_SELECTION, "%s", G_STRFUNC);
+
+  image = gimp_item_get_image (GIMP_ITEM (drawable));
+
+  drawable->private->floating_selection = fs;
+  gimp_image_set_floating_selection (image, fs);
+
+  /*  clear the selection  */
+  gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fs));
+
+  _gimp_drawable_add_floating_sel_filter (drawable);
+
+  g_signal_connect (fs, "update",
+                    G_CALLBACK (gimp_drawable_fs_update),
+                    drawable);
+
+  gimp_drawable_fs_update (fs,
+                           0, 0,
+                           gimp_item_get_width  (GIMP_ITEM (fs)),
+                           gimp_item_get_height (GIMP_ITEM (fs)),
+                           drawable);
+}
+
+void
+gimp_drawable_detach_floating_sel (GimpDrawable *drawable)
+{
+  GimpImage *image;
+  GimpLayer *fs;
+
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (gimp_drawable_get_floating_sel (drawable) != NULL);
+
+  GIMP_LOG (FLOATING_SELECTION, "%s", G_STRFUNC);
+
+  image = gimp_item_get_image (GIMP_ITEM (drawable));
+  fs    = drawable->private->floating_selection;
+
+  gimp_drawable_remove_fs_filter (drawable);
+
+  g_signal_handlers_disconnect_by_func (fs,
+                                        gimp_drawable_fs_update,
+                                        drawable);
+
+  gimp_drawable_fs_update (fs,
+                           0, 0,
+                           gimp_item_get_width  (GIMP_ITEM (fs)),
+                           gimp_item_get_height (GIMP_ITEM (fs)),
+                           drawable);
+
+  /*  clear the selection  */
+  gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fs));
+
+  gimp_image_set_floating_selection (image, NULL);
+  drawable->private->floating_selection = NULL;
+}
+
+GimpFilter *
+gimp_drawable_get_floating_sel_filter (GimpDrawable *drawable)
+{
+  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
+  g_return_val_if_fail (gimp_drawable_get_floating_sel (drawable) != NULL, NULL);
+
+  /* Ensure that the graph is construced before the filter is used.
+   * Otherwise, we rely on the projection to cause the graph to be
+   * constructed, which fails for images that aren't displayed.
+   */
+  gimp_filter_get_node (GIMP_FILTER (drawable));
+
+  return drawable->private->fs_filter;
+}
+
+
+/*  private functions  */
+
+void
+_gimp_drawable_add_floating_sel_filter (GimpDrawable *drawable)
+{
+  GimpDrawablePrivate *private = drawable->private;
+  GimpImage           *image   = gimp_item_get_image (GIMP_ITEM (drawable));
+  GimpLayer           *fs      = gimp_drawable_get_floating_sel (drawable);
+  GeglNode            *node;
+  GeglNode            *fs_source;
+  gboolean             linear;
+
+  if (! private->source_node)
+    return;
+
+  private->fs_filter = gimp_filter_new (_("Floating Selection"));
+  gimp_viewable_set_icon_name (GIMP_VIEWABLE (private->fs_filter),
+                               "gimp-floating-selection");
+
+  node = gimp_filter_get_node (private->fs_filter);
+
+  fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs));
+  linear    = gimp_drawable_get_linear (GIMP_DRAWABLE (fs));
+
+  /* rip the fs' source node out of its graph */
+  if (fs->layer_offset_node)
+    {
+      gegl_node_disconnect (fs->layer_offset_node, "input");
+      gegl_node_remove_child (gimp_filter_get_node (GIMP_FILTER (fs)),
+                              fs_source);
+    }
+
+  gegl_node_add_child (node, fs_source);
+
+  private->fs_applicator = gimp_applicator_new (node, linear,
+                                                FALSE, FALSE);
+
+  private->fs_crop_node =
+    gegl_node_new_child (node,
+                         "operation", "gegl:crop",
+                         NULL);
+
+  gegl_node_connect_to (fs_source,             "output",
+                        private->fs_crop_node, "input");
+  gegl_node_connect_to (private->fs_crop_node, "output",
+                        node,                  "aux");
+
+  gimp_drawable_add_filter (drawable, private->fs_filter);
+
+  g_signal_connect (fs, "notify",
+                    G_CALLBACK (gimp_drawable_fs_notify),
+                    drawable);
+  g_signal_connect (image, "component-active-changed",
+                    G_CALLBACK (gimp_drawable_fs_affect_changed),
+                    drawable);
+  g_signal_connect (image, "mask-changed",
+                    G_CALLBACK (gimp_drawable_fs_mask_changed),
+                    drawable);
+
+  gimp_drawable_sync_fs_filter (drawable);
+}
+
+
+/*  private functions  */
+
+static void
+gimp_drawable_remove_fs_filter (GimpDrawable *drawable)
+{
+  GimpDrawablePrivate *private = drawable->private;
+  GimpImage           *image   = gimp_item_get_image (GIMP_ITEM (drawable));
+  GimpLayer           *fs      = gimp_drawable_get_floating_sel (drawable);
+
+  if (private->fs_filter)
+    {
+      GeglNode *node;
+      GeglNode *fs_source;
+
+      g_signal_handlers_disconnect_by_func (fs,
+                                            gimp_drawable_fs_notify,
+                                            drawable);
+      g_signal_handlers_disconnect_by_func (image,
+                                            gimp_drawable_fs_affect_changed,
+                                            drawable);
+      g_signal_handlers_disconnect_by_func (image,
+                                            gimp_drawable_fs_mask_changed,
+                                            drawable);
+
+      gimp_drawable_remove_filter (drawable, private->fs_filter);
+
+      node = gimp_filter_get_node (private->fs_filter);
+
+      fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs));
+
+      gegl_node_remove_child (node, fs_source);
+
+      /* plug the fs' source node back into its graph */
+      if (fs->layer_offset_node)
+        {
+          gegl_node_add_child (gimp_filter_get_node (GIMP_FILTER (fs)),
+                               fs_source);
+          gegl_node_connect_to (fs_source,             "output",
+                                fs->layer_offset_node, "input");
+        }
+
+      g_object_unref (private->fs_filter);
+      private->fs_filter = NULL;
+
+      g_object_unref (private->fs_applicator);
+      private->fs_applicator = NULL;
+
+      private->fs_crop_node = NULL;
+    }
+}
+
+static void
+gimp_drawable_sync_fs_filter (GimpDrawable *drawable)
+{
+  GimpDrawablePrivate *private = drawable->private;
+  GimpImage           *image   = gimp_item_get_image (GIMP_ITEM (drawable));
+  GimpChannel         *mask    = gimp_image_get_mask (image);
+  GimpLayer           *fs      = gimp_drawable_get_floating_sel (drawable);
+  gint                off_x, off_y;
+  gint                fs_off_x, fs_off_y;
+
+  gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+  gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y);
+
+  gegl_node_set (private->fs_crop_node,
+                 "x",      (gdouble) (off_x - fs_off_x),
+                 "y",      (gdouble) (off_y - fs_off_y),
+                 "width",  (gdouble) gimp_item_get_width  (GIMP_ITEM (drawable)),
+                 "height", (gdouble) gimp_item_get_height (GIMP_ITEM (drawable)),
+                 NULL);
+
+  gimp_applicator_set_apply_offset (private->fs_applicator,
+                                    fs_off_x - off_x,
+                                    fs_off_y - off_y);
+
+  if (gimp_channel_is_empty (mask))
+    {
+      gimp_applicator_set_mask_buffer (private->fs_applicator, NULL);
+    }
+  else
+    {
+      GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
+
+      gimp_applicator_set_mask_buffer (private->fs_applicator, buffer);
+      gimp_applicator_set_mask_offset (private->fs_applicator,
+                                       -off_x, -off_y);
+    }
+
+  gimp_applicator_set_opacity (private->fs_applicator,
+                               gimp_layer_get_opacity (fs));
+  gimp_applicator_set_mode (private->fs_applicator,
+                            gimp_layer_get_mode (fs));
+  gimp_applicator_set_affect (private->fs_applicator,
+                              gimp_drawable_get_active_mask (drawable));
+}
+
+static void
+gimp_drawable_fs_notify (GimpLayer        *fs,
+                         const GParamSpec *pspec,
+                         GimpDrawable     *drawable)
+{
+  if (! strcmp (pspec->name, "offset-x") ||
+      ! strcmp (pspec->name, "offset-y") ||
+      ! strcmp (pspec->name, "visible")  ||
+      ! strcmp (pspec->name, "mode")     ||
+      ! strcmp (pspec->name, "opacity"))
+    {
+      gimp_drawable_sync_fs_filter (drawable);
+    }
+}
+
+static void
+gimp_drawable_fs_affect_changed (GimpImage       *image,
+                                 GimpChannelType  channel,
+                                 GimpDrawable    *drawable)
+{
+  GimpLayer *fs = gimp_drawable_get_floating_sel (drawable);
+
+  gimp_drawable_sync_fs_filter (drawable);
+
+  gimp_drawable_update (GIMP_DRAWABLE (fs),
+                        0, 0,
+                        gimp_item_get_width  (GIMP_ITEM (fs)),
+                        gimp_item_get_height (GIMP_ITEM (fs)));
+}
+
+static void
+gimp_drawable_fs_mask_changed (GimpImage    *image,
+                               GimpDrawable *drawable)
+{
+  GimpLayer *fs = gimp_drawable_get_floating_sel (drawable);
+
+  gimp_drawable_sync_fs_filter (drawable);
+
+  gimp_drawable_update (GIMP_DRAWABLE (fs),
+                        0, 0,
+                        gimp_item_get_width  (GIMP_ITEM (fs)),
+                        gimp_item_get_height (GIMP_ITEM (fs)));
+}
+
+static void
+gimp_drawable_fs_update (GimpLayer    *fs,
+                         gint          x,
+                         gint          y,
+                         gint          width,
+                         gint          height,
+                         GimpDrawable *drawable)
+{
+  gint fs_off_x, fs_off_y;
+  gint off_x, off_y;
+  gint dr_x, dr_y, dr_width, dr_height;
+
+  gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y);
+  gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+
+  if (gimp_rectangle_intersect (x + fs_off_x,
+                                y + fs_off_y,
+                                width,
+                                height,
+                                off_x,
+                                off_y,
+                                gimp_item_get_width  (GIMP_ITEM (drawable)),
+                                gimp_item_get_height (GIMP_ITEM (drawable)),
+                                &dr_x,
+                                &dr_y,
+                                &dr_width,
+                                &dr_height))
+    {
+      gimp_drawable_update (drawable,
+                            dr_x - off_x, dr_y - off_y,
+                            dr_width, dr_height);
+    }
+}
diff --git a/app/core/gimpdrawable-floating-selection.h b/app/core/gimpdrawable-floating-selection.h
new file mode 100644
index 0000000..ef18674
--- /dev/null
+++ b/app/core/gimpdrawable-floating-selection.h
@@ -0,0 +1,31 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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/>.
+ */
+
+#ifndef __GIMP_DRAWABLE_FLOATING_SELECTION_H__
+#define __GIMP_DRAWABLE_FLOATING_SELECTION_H__
+
+
+GimpLayer  * gimp_drawable_get_floating_sel          (GimpDrawable *drawable);
+void         gimp_drawable_attach_floating_sel       (GimpDrawable *drawable,
+                                                      GimpLayer    *floating_sel);
+void         gimp_drawable_detach_floating_sel       (GimpDrawable *drawable);
+GimpFilter * gimp_drawable_get_floating_sel_filter   (GimpDrawable *drawable);
+
+void         _gimp_drawable_add_floating_sel_filter  (GimpDrawable *drawable);
+
+
+#endif /* __GIMP_DRAWABLE_FLOATING_SELECTION_H__ */
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 8ce84d4..4a65c7a 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -26,7 +26,6 @@
 
 #include "core-types.h"
 
-#include "gegl/gimpapplicator.h"
 #include "gegl/gimp-babl.h"
 #include "gegl/gimp-gegl-apply-operation.h"
 #include "gegl/gimp-gegl-utils.h"
@@ -36,7 +35,7 @@
 #include "gimpchannel.h"
 #include "gimpcontext.h"
 #include "gimpdrawable-combine.h"
-#include "gimpdrawable-filters.h"
+#include "gimpdrawable-floating-selection.h"
 #include "gimpdrawable-preview.h"
 #include "gimpdrawable-private.h"
 #include "gimpdrawable-shadow.h"
@@ -45,9 +44,7 @@
 #include "gimpimage.h"
 #include "gimpimage-colormap.h"
 #include "gimpimage-undo-push.h"
-#include "gimplayer.h"
 #include "gimpmarshal.h"
-#include "gimppattern.h"
 #include "gimppickable.h"
 #include "gimpprogress.h"
 
@@ -185,23 +182,6 @@ static void       gimp_drawable_real_swap_pixels   (GimpDrawable      *drawable,
                                                     gint               x,
                                                     gint               y);
 
-static void       gimp_drawable_sync_fs_filter     (GimpDrawable      *drawable,
-                                                    gboolean           detach_fs);
-static void       gimp_drawable_fs_notify          (GimpLayer         *fs,
-                                                    const GParamSpec  *pspec,
-                                                    GimpDrawable      *drawable);
-static void       gimp_drawable_fs_affect_changed  (GimpImage         *image,
-                                                    GimpChannelType    channel,
-                                                    GimpDrawable      *drawable);
-static void       gimp_drawable_fs_mask_changed    (GimpImage         *image,
-                                                    GimpDrawable      *drawable);
-static void       gimp_drawable_fs_update          (GimpLayer         *fs,
-                                                    gint               x,
-                                                    gint               y,
-                                                    gint               width,
-                                                    gint               height,
-                                                    GimpDrawable      *drawable);
-
 
 G_DEFINE_TYPE_WITH_CODE (GimpDrawable, gimp_drawable, GIMP_TYPE_ITEM,
                          G_IMPLEMENT_INTERFACE (GIMP_TYPE_COLOR_MANAGED,
@@ -946,232 +926,6 @@ gimp_drawable_real_swap_pixels (GimpDrawable *drawable,
   gimp_drawable_update (drawable, x, y, width, height);
 }
 
-static void
-gimp_drawable_sync_fs_filter (GimpDrawable *drawable,
-                              gboolean      detach_fs)
-{
-  GimpDrawablePrivate *private = drawable->private;
-  GimpImage           *image   = gimp_item_get_image (GIMP_ITEM (drawable));
-  GimpLayer           *fs      = gimp_drawable_get_floating_sel (drawable);
-
-  if (! private->source_node)
-    return;
-
-  if (fs && ! detach_fs)
-    {
-      GimpImage   *image = gimp_item_get_image (GIMP_ITEM (drawable));
-      GimpChannel *mask  = gimp_image_get_mask (image);
-      gint         off_x, off_y;
-      gint         fs_off_x, fs_off_y;
-
-      if (! private->fs_filter)
-        {
-          GeglNode *node;
-          GeglNode *fs_source;
-          gboolean  linear;
-
-          private->fs_filter = gimp_filter_new ("Floating Selection");
-          gimp_viewable_set_icon_name (GIMP_VIEWABLE (private->fs_filter),
-                                       "gimp-floating-selection");
-
-          node = gimp_filter_get_node (private->fs_filter);
-
-          fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs));
-          linear    = gimp_drawable_get_linear (GIMP_DRAWABLE (fs));
-
-          /* rip the fs' source node out of its graph */
-          if (fs->layer_offset_node)
-            {
-              gegl_node_disconnect (fs->layer_offset_node, "input");
-              gegl_node_remove_child (gimp_filter_get_node (GIMP_FILTER (fs)),
-                                      fs_source);
-            }
-
-          gegl_node_add_child (node, fs_source);
-
-          private->fs_applicator = gimp_applicator_new (node, linear,
-                                                        FALSE, FALSE);
-
-          private->fs_crop_node =
-            gegl_node_new_child (node,
-                                 "operation", "gegl:crop",
-                                 NULL);
-
-          gegl_node_connect_to (fs_source,             "output",
-                                private->fs_crop_node, "input");
-          gegl_node_connect_to (private->fs_crop_node, "output",
-                                node,                  "aux");
-
-          gimp_drawable_add_filter (drawable, private->fs_filter);
-
-          g_signal_connect (fs, "notify",
-                            G_CALLBACK (gimp_drawable_fs_notify),
-                            drawable);
-          g_signal_connect (image, "component-active-changed",
-                            G_CALLBACK (gimp_drawable_fs_affect_changed),
-                            drawable);
-          g_signal_connect (image, "mask-changed",
-                            G_CALLBACK (gimp_drawable_fs_mask_changed),
-                            drawable);
-        }
-
-      gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
-      gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y);
-
-      gegl_node_set (private->fs_crop_node,
-                     "x",      (gdouble) (off_x - fs_off_x),
-                     "y",      (gdouble) (off_y - fs_off_y),
-                     "width",  (gdouble) gimp_item_get_width  (GIMP_ITEM (drawable)),
-                     "height", (gdouble) gimp_item_get_height (GIMP_ITEM (drawable)),
-                     NULL);
-
-      gimp_applicator_set_apply_offset (private->fs_applicator,
-                                        fs_off_x - off_x,
-                                        fs_off_y - off_y);
-
-      if (gimp_channel_is_empty (mask))
-        {
-          gimp_applicator_set_mask_buffer (private->fs_applicator, NULL);
-        }
-      else
-        {
-          GeglBuffer *buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
-
-          gimp_applicator_set_mask_buffer (private->fs_applicator, buffer);
-          gimp_applicator_set_mask_offset (private->fs_applicator,
-                                           -off_x, -off_y);
-        }
-
-      gimp_applicator_set_opacity (private->fs_applicator,
-                                   gimp_layer_get_opacity (fs));
-      gimp_applicator_set_mode (private->fs_applicator,
-                                gimp_layer_get_mode (fs));
-      gimp_applicator_set_affect (private->fs_applicator,
-                                  gimp_drawable_get_active_mask (drawable));
-    }
-  else
-    {
-      if (private->fs_filter)
-        {
-          GeglNode *node;
-          GeglNode *fs_source;
-
-          g_signal_handlers_disconnect_by_func (fs,
-                                                gimp_drawable_fs_notify,
-                                                drawable);
-          g_signal_handlers_disconnect_by_func (image,
-                                                gimp_drawable_fs_affect_changed,
-                                                drawable);
-          g_signal_handlers_disconnect_by_func (image,
-                                                gimp_drawable_fs_mask_changed,
-                                                drawable);
-
-          gimp_drawable_remove_filter (drawable, private->fs_filter);
-
-          node = gimp_filter_get_node (private->fs_filter);
-
-          fs_source = gimp_drawable_get_source_node (GIMP_DRAWABLE (fs));
-
-          gegl_node_remove_child (node, fs_source);
-
-          /* plug the fs' source node back into its graph */
-          if (fs->layer_offset_node)
-            {
-              gegl_node_add_child (gimp_filter_get_node (GIMP_FILTER (fs)),
-                                   fs_source);
-              gegl_node_connect_to (fs_source,             "output",
-                                    fs->layer_offset_node, "input");
-            }
-
-          g_object_unref (private->fs_filter);
-          private->fs_filter = NULL;
-
-          g_object_unref (private->fs_applicator);
-          private->fs_applicator = NULL;
-
-          private->fs_crop_node = NULL;
-        }
-    }
-}
-
-static void
-gimp_drawable_fs_notify (GimpLayer        *fs,
-                         const GParamSpec *pspec,
-                         GimpDrawable     *drawable)
-{
-  if (! strcmp (pspec->name, "offset-x") ||
-      ! strcmp (pspec->name, "offset-y") ||
-      ! strcmp (pspec->name, "visible")  ||
-      ! strcmp (pspec->name, "mode")     ||
-      ! strcmp (pspec->name, "opacity"))
-    {
-      gimp_drawable_sync_fs_filter (drawable, FALSE);
-    }
-}
-
-static void
-gimp_drawable_fs_affect_changed (GimpImage       *image,
-                                 GimpChannelType  channel,
-                                 GimpDrawable    *drawable)
-{
-  GimpLayer *fs = gimp_drawable_get_floating_sel (drawable);
-
-  gimp_drawable_sync_fs_filter (drawable, FALSE);
-
-  gimp_drawable_update (GIMP_DRAWABLE (fs),
-                        0, 0,
-                        gimp_item_get_width  (GIMP_ITEM (fs)),
-                        gimp_item_get_height (GIMP_ITEM (fs)));
-}
-
-static void
-gimp_drawable_fs_mask_changed (GimpImage       *image,
-                               GimpDrawable    *drawable)
-{
-  GimpLayer *fs = gimp_drawable_get_floating_sel (drawable);
-
-  gimp_drawable_sync_fs_filter (drawable, FALSE);
-
-  gimp_drawable_update (GIMP_DRAWABLE (fs),
-                        0, 0,
-                        gimp_item_get_width  (GIMP_ITEM (fs)),
-                        gimp_item_get_height (GIMP_ITEM (fs)));
-}
-
-static void
-gimp_drawable_fs_update (GimpLayer    *fs,
-                         gint          x,
-                         gint          y,
-                         gint          width,
-                         gint          height,
-                         GimpDrawable *drawable)
-{
-  gint fs_off_x, fs_off_y;
-  gint off_x, off_y;
-  gint dr_x, dr_y, dr_width, dr_height;
-
-  gimp_item_get_offset (GIMP_ITEM (fs), &fs_off_x, &fs_off_y);
-  gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
-
-  if (gimp_rectangle_intersect (x + fs_off_x,
-                                y + fs_off_y,
-                                width,
-                                height,
-                                off_x,
-                                off_y,
-                                gimp_item_get_width  (GIMP_ITEM (drawable)),
-                                gimp_item_get_height (GIMP_ITEM (drawable)),
-                                &dr_x,
-                                &dr_y,
-                                &dr_width,
-                                &dr_height))
-    {
-      gimp_drawable_update (drawable,
-                            dr_x - off_x, dr_y - off_y,
-                            dr_width, dr_height);
-    }
-}
-
 
 /*  public functions  */
 
@@ -1478,7 +1232,8 @@ gimp_drawable_get_source_node (GimpDrawable *drawable)
   gegl_node_connect_to (filter, "output",
                         output, "input");
 
-  gimp_drawable_sync_fs_filter (drawable, FALSE);
+  if (gimp_drawable_get_floating_sel (drawable))
+    _gimp_drawable_add_floating_sel_filter (drawable);
 
   return drawable->private->source_node;
 }
@@ -1732,94 +1487,3 @@ gimp_drawable_get_colormap (const GimpDrawable *drawable)
 
   return image ? gimp_image_get_colormap (image) : NULL;
 }
-
-GimpLayer *
-gimp_drawable_get_floating_sel (const GimpDrawable *drawable)
-{
-  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
-
-  return drawable->private->floating_selection;
-}
-
-void
-gimp_drawable_attach_floating_sel (GimpDrawable *drawable,
-                                   GimpLayer    *fs)
-{
-  GimpImage *image;
-
-  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
-  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
-  g_return_if_fail (gimp_drawable_get_floating_sel (drawable) == NULL);
-  g_return_if_fail (GIMP_IS_LAYER (fs));
-
-  GIMP_LOG (FLOATING_SELECTION, "%s", G_STRFUNC);
-
-  image = gimp_item_get_image (GIMP_ITEM (drawable));
-
-  drawable->private->floating_selection = fs;
-  gimp_image_set_floating_selection (image, fs);
-
-  /*  clear the selection  */
-  gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fs));
-
-  gimp_drawable_sync_fs_filter (drawable, FALSE);
-
-  g_signal_connect (fs, "update",
-                    G_CALLBACK (gimp_drawable_fs_update),
-                    drawable);
-
-  gimp_drawable_fs_update (fs,
-                           0, 0,
-                           gimp_item_get_width  (GIMP_ITEM (fs)),
-                           gimp_item_get_height (GIMP_ITEM (fs)),
-                           drawable);
-}
-
-void
-gimp_drawable_detach_floating_sel (GimpDrawable *drawable)
-{
-  GimpImage *image;
-  GimpLayer *fs;
-
-  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
-  g_return_if_fail (gimp_drawable_get_floating_sel (drawable) != NULL);
-
-  GIMP_LOG (FLOATING_SELECTION, "%s", G_STRFUNC);
-
-  image = gimp_item_get_image (GIMP_ITEM (drawable));
-  fs    = drawable->private->floating_selection;
-
-  gimp_drawable_sync_fs_filter (drawable, TRUE);
-
-  g_signal_handlers_disconnect_by_func (fs,
-                                        gimp_drawable_fs_update,
-                                        drawable);
-
-  gimp_drawable_fs_update (fs,
-                           0, 0,
-                           gimp_item_get_width  (GIMP_ITEM (fs)),
-                           gimp_item_get_height (GIMP_ITEM (fs)),
-                           drawable);
-
-  /*  clear the selection  */
-  gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (fs));
-
-  gimp_image_set_floating_selection (image, NULL);
-  drawable->private->floating_selection = NULL;
-}
-
-GimpFilter *
-gimp_drawable_get_floating_sel_filter (GimpDrawable *drawable)
-{
-  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
-  g_return_val_if_fail (gimp_drawable_get_floating_sel (drawable) != NULL, NULL);
-
-  /*
-   * Ensure that the graph is construced before the filter is used.
-   * Otherwise, we rely on the projection to cause the graph to be constructed,
-   * which fails for images that aren't displayed.
-   */
-  gimp_filter_get_node (GIMP_FILTER (drawable));
-
-  return drawable->private->fs_filter;
-}
diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h
index 3cb35e3..52fc8c3 100644
--- a/app/core/gimpdrawable.h
+++ b/app/core/gimpdrawable.h
@@ -220,12 +220,5 @@ gint          gimp_drawable_get_component_index  (const GimpDrawable *drawable,
 
 const guchar  * gimp_drawable_get_colormap       (const GimpDrawable *drawable);
 
-GimpLayer    * gimp_drawable_get_floating_sel    (const GimpDrawable *drawable);
-void           gimp_drawable_attach_floating_sel (GimpDrawable       *drawable,
-                                                  GimpLayer          *floating_sel);
-void           gimp_drawable_detach_floating_sel (GimpDrawable       *drawable);
-GimpFilter *
-           gimp_drawable_get_floating_sel_filter (GimpDrawable       *drawable);
-
 
 #endif /* __GIMP_DRAWABLE_H__ */
diff --git a/app/core/gimpfloatingselundo.c b/app/core/gimpfloatingselundo.c
index d39ae00..b7ff3d2 100644
--- a/app/core/gimpfloatingselundo.c
+++ b/app/core/gimpfloatingselundo.c
@@ -22,6 +22,7 @@
 
 #include "core-types.h"
 
+#include "gimpdrawable-floating-selection.h"
 #include "gimpfloatingselundo.h"
 #include "gimpimage.h"
 #include "gimplayer.h"
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 7e6eb95..a6654e5 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -41,6 +41,7 @@
 #include "gimp-parasites.h"
 #include "gimp-utils.h"
 #include "gimpcontext.h"
+#include "gimpdrawable-floating-selection.h"
 #include "gimpdrawablestack.h"
 #include "gimpgrid.h"
 #include "gimperror.h"
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index b95515c..ebbe011 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -40,6 +40,7 @@
 #include "gimpchannel-select.h"
 #include "gimpcontext.h"
 #include "gimpcontainer.h"
+#include "gimpdrawable-floating-selection.h"
 #include "gimperror.h"
 #include "gimpimage-undo-push.h"
 #include "gimpimage-undo.h"
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7dd389d..5df36ac 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -125,6 +125,7 @@ app/core/gimpdrawable.c
 app/core/gimpdrawable-blend.c
 app/core/gimpdrawable-bucket-fill.c
 app/core/gimpdrawable-equalize.c
+app/core/gimpdrawable-floating-selection.c
 app/core/gimpdrawable-foreground-extract.c
 app/core/gimpdrawable-fill.c
 app/core/gimpdrawable-levels.c


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