[gimp] app: make GimpImageMap a subclass of GimpFilter



commit 477987dce3f2021c43915a3a323fcd50b3324e1d
Author: Michael Natterer <mitch gimp org>
Date:   Mon May 9 21:37:13 2016 +0200

    app: make GimpImageMap a subclass of GimpFilter
    
    Reduces members and all sorts of duplication and is a much better
    abstraction of what it does. Also make it a lot smarter and
    self-updating, chop up the apply() function and move its parts where
    they belong. Also, it's now aware of selection changes and does the
    right thing.
    
    Don't abort GimpImageMapTool on selection changes, it now nicely
    handles that.

 app/core/gimpimagemap.c      |  525 ++++++++++++++++++++----------------------
 app/core/gimpimagemap.h      |    4 +-
 app/tools/gimpimagemaptool.c |    1 -
 3 files changed, 257 insertions(+), 273 deletions(-)
---
diff --git a/app/core/gimpimagemap.c b/app/core/gimpimagemap.c
index 03a283c..dc7e06a 100644
--- a/app/core/gimpimagemap.c
+++ b/app/core/gimpimagemap.c
@@ -55,12 +55,10 @@ enum
 
 struct _GimpImageMap
 {
-  GimpObject            parent_instance;
+  GimpFilter            parent_instance;
 
   GimpDrawable         *drawable;
-  gchar                *undo_desc;
   GeglNode             *operation;
-  gchar                *icon_name;
 
   GimpImageMapRegion    region;
   gboolean              preview_enabled;
@@ -72,7 +70,6 @@ struct _GimpImageMap
 
   GeglRectangle         filter_area;
 
-  GimpFilter           *filter;
   GeglNode             *translate;
   GeglNode             *crop;
   GeglNode             *cast_before;
@@ -91,6 +88,7 @@ static void       gimp_image_map_sync_preview    (GimpImageMap        *image_map
                                                   gdouble              old_position);
 static void       gimp_image_map_sync_mode       (GimpImageMap        *image_map);
 static void       gimp_image_map_sync_affect     (GimpImageMap        *image_map);
+static void       gimp_image_map_sync_mask       (GimpImageMap        *image_map);
 static void       gimp_image_map_sync_gamma_hack (GimpImageMap        *image_map);
 
 static gboolean   gimp_image_map_is_filtering    (GimpImageMap        *image_map);
@@ -103,9 +101,11 @@ static void       gimp_image_map_update_drawable (GimpImageMap        *image_map
 static void       gimp_image_map_affect_changed  (GimpImage           *image,
                                                   GimpChannelType      channel,
                                                   GimpImageMap        *image_map);
+static void       gimp_image_map_mask_changed    (GimpImage           *image,
+                                                  GimpImageMap        *image_map);
 
 
-G_DEFINE_TYPE (GimpImageMap, gimp_image_map, GIMP_TYPE_OBJECT)
+G_DEFINE_TYPE (GimpImageMap, gimp_image_map, GIMP_TYPE_FILTER)
 
 #define parent_class gimp_image_map_parent_class
 
@@ -159,30 +159,12 @@ gimp_image_map_finalize (GObject *object)
 {
   GimpImageMap *image_map = GIMP_IMAGE_MAP (object);
 
-  if (image_map->undo_desc)
-    {
-      g_free (image_map->undo_desc);
-      image_map->undo_desc = NULL;
-    }
-
   if (image_map->operation)
     {
       g_object_unref (image_map->operation);
       image_map->operation = NULL;
     }
 
-  if (image_map->icon_name)
-    {
-      g_free (image_map->icon_name);
-      image_map->icon_name = NULL;
-    }
-
-  if (image_map->filter)
-    {
-      g_object_unref (image_map->filter);
-      image_map->filter = NULL;
-    }
-
   if (image_map->applicator)
     {
       g_object_unref (image_map->applicator);
@@ -205,22 +187,68 @@ gimp_image_map_new (GimpDrawable *drawable,
                     const gchar  *icon_name)
 {
   GimpImageMap *image_map;
+  GeglNode     *filter_node;
 
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
   g_return_val_if_fail (GEGL_IS_NODE (operation), NULL);
   g_return_val_if_fail (gegl_node_has_pad (operation, "output"), NULL);
 
-  image_map = g_object_new (GIMP_TYPE_IMAGE_MAP, NULL);
+  image_map = g_object_new (GIMP_TYPE_IMAGE_MAP,
+                            "name",      undo_desc,
+                            "icon-name", icon_name,
+                            NULL);
 
   image_map->drawable  = g_object_ref (drawable);
-  image_map->undo_desc = g_strdup (undo_desc);
-
   image_map->operation = g_object_ref (operation);
-  image_map->icon_name = g_strdup (icon_name);
 
   gimp_viewable_preview_freeze (GIMP_VIEWABLE (drawable));
 
+  filter_node = gimp_filter_get_node (GIMP_FILTER (image_map));
+
+  gegl_node_add_child (filter_node, operation);
+
+  image_map->applicator =
+    gimp_applicator_new (filter_node,
+                         gimp_drawable_get_linear (image_map->drawable),
+                         TRUE, TRUE);
+
+  gimp_filter_set_applicator (GIMP_FILTER (image_map),
+                              image_map->applicator);
+
+  image_map->translate = gegl_node_new_child (filter_node,
+                                              "operation", "gegl:translate",
+                                              NULL);
+  image_map->crop = gegl_node_new_child (filter_node,
+                                         "operation", "gegl:crop",
+                                         NULL);
+
+  image_map->cast_before = gegl_node_new_child (filter_node,
+                                                "operation", "gegl:nop",
+                                                NULL);
+  image_map->cast_after = gegl_node_new_child (filter_node,
+                                               "operation", "gegl:nop",
+                                               NULL);
+
+  if (gegl_node_has_pad (image_map->operation, "input"))
+    {
+      GeglNode *input = gegl_node_get_input_proxy (filter_node, "input");
+
+      gegl_node_link_many (input,
+                           image_map->translate,
+                           image_map->crop,
+                           image_map->cast_before,
+                           image_map->operation,
+                           NULL);
+    }
+
+  gegl_node_link_many (image_map->operation,
+                       image_map->cast_after,
+                       NULL);
+
+  gegl_node_connect_to (image_map->cast_after, "output",
+                        filter_node,           "aux");
+
   return image_map;
 }
 
@@ -237,7 +265,7 @@ gimp_image_map_set_region (GimpImageMap       *image_map,
       gimp_image_map_sync_region (image_map);
 
       if (gimp_image_map_is_filtering (image_map))
-        gimp_image_map_update_drawable (image_map, &image_map->filter_area);
+        gimp_image_map_update_drawable (image_map, NULL);
     }
 }
 
@@ -288,7 +316,7 @@ gimp_image_map_set_mode (GimpImageMap         *image_map,
       gimp_image_map_sync_mode (image_map);
 
       if (gimp_image_map_is_filtering (image_map))
-        gimp_image_map_update_drawable (image_map, &image_map->filter_area);
+        gimp_image_map_update_drawable (image_map, NULL);
     }
 }
 
@@ -305,7 +333,7 @@ gimp_image_map_set_gamma_hack (GimpImageMap *image_map,
       gimp_image_map_sync_gamma_hack (image_map);
 
       if (gimp_image_map_is_filtering (image_map))
-        gimp_image_map_update_drawable (image_map, &image_map->filter_area);
+        gimp_image_map_update_drawable (image_map, NULL);
     }
 }
 
@@ -313,9 +341,7 @@ void
 gimp_image_map_apply (GimpImageMap        *image_map,
                       const GeglRectangle *area)
 {
-  GimpImage     *image;
-  GimpChannel   *mask;
-  GeglRectangle  update_area;
+  GeglRectangle update_area;
 
   g_return_if_fail (GIMP_IS_IMAGE_MAP (image_map));
 
@@ -333,7 +359,6 @@ gimp_image_map_apply (GimpImageMap        *image_map,
                                   &image_map->filter_area.width,
                                   &image_map->filter_area.height))
     {
-      gimp_image_map_remove_filter (image_map);
       return;
     }
 
@@ -355,95 +380,9 @@ gimp_image_map_apply (GimpImageMap        *image_map,
                                        &update_area.width,
                                        &update_area.height))
     {
-      /* Bail out, but don't remove the filter */
       return;
     }
 
-  if (! image_map->filter)
-    {
-      GeglNode *filter_node;
-
-      image_map->filter = gimp_filter_new (image_map->undo_desc);
-      gimp_viewable_set_icon_name (GIMP_VIEWABLE (image_map->filter),
-                                   image_map->icon_name);
-
-      filter_node = gimp_filter_get_node (image_map->filter);
-
-      gegl_node_add_child (filter_node, image_map->operation);
-
-      image_map->applicator =
-        gimp_applicator_new (filter_node,
-                             gimp_drawable_get_linear (image_map->drawable),
-                             TRUE, TRUE);
-
-      gimp_filter_set_applicator (image_map->filter,
-                                  image_map->applicator);
-
-      image_map->translate = gegl_node_new_child (filter_node,
-                                                  "operation", "gegl:translate",
-                                                  NULL);
-      image_map->crop = gegl_node_new_child (filter_node,
-                                             "operation", "gegl:crop",
-                                             NULL);
-
-      image_map->cast_before = gegl_node_new_child (filter_node,
-                                                    "operation", "gegl:nop",
-                                                    NULL);
-      image_map->cast_after = gegl_node_new_child (filter_node,
-                                                   "operation", "gegl:nop",
-                                                   NULL);
-
-      gimp_image_map_sync_region (image_map);
-      gimp_image_map_sync_preview (image_map,
-                                   image_map->preview_enabled,
-                                   image_map->preview_alignment,
-                                   image_map->preview_position);
-      gimp_image_map_sync_mode (image_map);
-      gimp_image_map_sync_gamma_hack (image_map);
-
-      if (gegl_node_has_pad (image_map->operation, "input"))
-        {
-          GeglNode *input = gegl_node_get_input_proxy (filter_node, "input");
-
-          gegl_node_link_many (input,
-                               image_map->translate,
-                               image_map->crop,
-                               image_map->cast_before,
-                               image_map->operation,
-                               NULL);
-        }
-
-      gegl_node_link_many (image_map->operation,
-                           image_map->cast_after,
-                           NULL);
-
-      gegl_node_connect_to (image_map->cast_after, "output",
-                            filter_node,           "aux");
-    }
-
-  gimp_image_map_sync_affect (image_map);
-
-  image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
-  mask  = gimp_image_get_mask (image);
-
-  if (gimp_channel_is_empty (mask))
-    {
-      gimp_applicator_set_mask_buffer (image_map->applicator, NULL);
-    }
-  else
-    {
-      GeglBuffer *mask_buffer;
-      gint        offset_x, offset_y;
-
-      mask_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
-      gimp_item_get_offset (GIMP_ITEM (image_map->drawable),
-                            &offset_x, &offset_y);
-
-      gimp_applicator_set_mask_buffer (image_map->applicator, mask_buffer);
-      gimp_applicator_set_mask_offset (image_map->applicator,
-                                       -offset_x, -offset_y);
-    }
-
   gimp_image_map_add_filter (image_map);
   gimp_image_map_update_drawable (image_map, &update_area);
 }
@@ -461,9 +400,9 @@ gimp_image_map_commit (GimpImageMap *image_map,
   if (gimp_image_map_is_filtering (image_map))
     {
       success = gimp_drawable_merge_filter (image_map->drawable,
-                                            image_map->filter,
+                                            GIMP_FILTER (image_map),
                                             progress,
-                                            image_map->undo_desc,
+                                            gimp_object_get_name (image_map),
                                             cancellable);
 
       gimp_image_map_remove_filter (image_map);
@@ -481,7 +420,7 @@ gimp_image_map_abort (GimpImageMap *image_map)
 
   if (gimp_image_map_remove_filter (image_map))
     {
-      gimp_image_map_update_drawable (image_map, &image_map->filter_area);
+      gimp_image_map_update_drawable (image_map, NULL);
     }
 }
 
@@ -491,42 +430,39 @@ gimp_image_map_abort (GimpImageMap *image_map)
 static void
 gimp_image_map_sync_region (GimpImageMap *image_map)
 {
-  if (image_map->applicator)
+  if (image_map->region == GIMP_IMAGE_MAP_REGION_SELECTION)
     {
-      if (image_map->region == GIMP_IMAGE_MAP_REGION_SELECTION)
-        {
-          gegl_node_set (image_map->translate,
-                         "x", (gdouble) -image_map->filter_area.x,
-                         "y", (gdouble) -image_map->filter_area.y,
-                         NULL);
-
-          gegl_node_set (image_map->crop,
-                         "width",  (gdouble) image_map->filter_area.width,
-                         "height", (gdouble) image_map->filter_area.height,
-                         NULL);
-
-          gimp_applicator_set_apply_offset (image_map->applicator,
-                                            image_map->filter_area.x,
-                                            image_map->filter_area.y);
-        }
-      else
-        {
-          GimpItem *item   = GIMP_ITEM (image_map->drawable);
-          gdouble   width  = gimp_item_get_width (item);
-          gdouble   height = gimp_item_get_height (item);
+      gegl_node_set (image_map->translate,
+                     "x", (gdouble) -image_map->filter_area.x,
+                     "y", (gdouble) -image_map->filter_area.y,
+                     NULL);
+
+      gegl_node_set (image_map->crop,
+                     "width",  (gdouble) image_map->filter_area.width,
+                     "height", (gdouble) image_map->filter_area.height,
+                     NULL);
+
+      gimp_applicator_set_apply_offset (image_map->applicator,
+                                        image_map->filter_area.x,
+                                        image_map->filter_area.y);
+    }
+  else
+    {
+      GimpItem *item   = GIMP_ITEM (image_map->drawable);
+      gdouble   width  = gimp_item_get_width (item);
+      gdouble   height = gimp_item_get_height (item);
 
-          gegl_node_set (image_map->translate,
-                         "x", (gdouble) 0.0,
-                         "y", (gdouble) 0.0,
-                         NULL);
+      gegl_node_set (image_map->translate,
+                     "x", (gdouble) 0.0,
+                     "y", (gdouble) 0.0,
+                     NULL);
 
-          gegl_node_set (image_map->crop,
-                         "width",  width,
-                         "height", height,
-                         NULL);
+      gegl_node_set (image_map->crop,
+                     "width",  width,
+                     "height", height,
+                     NULL);
 
-          gimp_applicator_set_apply_offset (image_map->applicator, 0, 0);
-        }
+      gimp_applicator_set_apply_offset (image_map->applicator, 0, 0);
     }
 }
 
@@ -582,141 +518,151 @@ gimp_image_map_sync_preview (GimpImageMap      *image_map,
                              GimpAlignmentType  old_alignment,
                              gdouble            old_position)
 {
-  if (image_map->applicator)
-    {
-      GeglRectangle old_rect;
-      GeglRectangle new_rect;
-
-      gimp_image_map_get_preview_rect (image_map,
-                                       old_enabled,
-                                       old_alignment,
-                                       old_position,
-                                       &old_rect);
-
-      gimp_image_map_get_preview_rect (image_map,
-                                       image_map->preview_enabled,
-                                       image_map->preview_alignment,
-                                       image_map->preview_position,
-                                       &new_rect);
-
-      gimp_applicator_set_preview (image_map->applicator,
+  GeglRectangle old_rect;
+  GeglRectangle new_rect;
+
+  gimp_image_map_get_preview_rect (image_map,
+                                   old_enabled,
+                                   old_alignment,
+                                   old_position,
+                                   &old_rect);
+
+  gimp_image_map_get_preview_rect (image_map,
                                    image_map->preview_enabled,
+                                   image_map->preview_alignment,
+                                   image_map->preview_position,
                                    &new_rect);
 
-      if (old_rect.x      != new_rect.x     ||
-          old_rect.y      != new_rect.y     ||
-          old_rect.width  != new_rect.width ||
-          old_rect.height != new_rect.height)
-        {
-          cairo_region_t *region;
-          gint            n_rects;
-          gint            i;
+  gimp_applicator_set_preview (image_map->applicator,
+                               image_map->preview_enabled,
+                               &new_rect);
 
-          region = cairo_region_create_rectangle ((cairo_rectangle_int_t *)
-                                                  &old_rect);
-          cairo_region_xor_rectangle (region,
-                                      (cairo_rectangle_int_t *) &new_rect);
+  if (old_rect.x      != new_rect.x     ||
+      old_rect.y      != new_rect.y     ||
+      old_rect.width  != new_rect.width ||
+      old_rect.height != new_rect.height)
+    {
+      cairo_region_t *region;
+      gint            n_rects;
+      gint            i;
 
-          n_rects = cairo_region_num_rectangles (region);
+      region = cairo_region_create_rectangle ((cairo_rectangle_int_t *)
+                                              &old_rect);
+      cairo_region_xor_rectangle (region,
+                                  (cairo_rectangle_int_t *) &new_rect);
 
-          for (i = 0; i < n_rects; i++)
-            {
-              cairo_rectangle_int_t rect;
+      n_rects = cairo_region_num_rectangles (region);
 
-              cairo_region_get_rectangle (region, i, &rect);
+      for (i = 0; i < n_rects; i++)
+        {
+          cairo_rectangle_int_t rect;
 
-              gimp_image_map_update_drawable (image_map,
-                                              (const GeglRectangle *) &rect);
-            }
+          cairo_region_get_rectangle (region, i, &rect);
 
-          cairo_region_destroy (region);
+          gimp_image_map_update_drawable (image_map,
+                                          (const GeglRectangle *) &rect);
         }
+
+      cairo_region_destroy (region);
     }
 }
 
 static void
 gimp_image_map_sync_mode (GimpImageMap *image_map)
 {
-  if (image_map->applicator)
-    gimp_applicator_set_mode (image_map->applicator,
-                              image_map->opacity,
-                              image_map->paint_mode);
+  gimp_applicator_set_mode (image_map->applicator,
+                            image_map->opacity,
+                            image_map->paint_mode);
 }
 
 static void
 gimp_image_map_sync_affect (GimpImageMap *image_map)
 {
-  if (image_map->applicator)
-    {
-      GimpComponentMask active_mask;
+  GimpComponentMask active_mask;
+
+  active_mask = gimp_drawable_get_active_mask (image_map->drawable);
+
+  /*  don't let the filter affect the drawable projection's alpha,
+   *  because it can't affect the drawable buffer's alpha either when
+   *  finally merged (see bug #699279)
+   */
+  if (! gimp_drawable_has_alpha (image_map->drawable))
+    active_mask &= ~GIMP_COMPONENT_MASK_ALPHA;
+
+  gimp_applicator_set_affect (image_map->applicator, active_mask);
+}
 
-      active_mask = gimp_drawable_get_active_mask (image_map->drawable);
+static void
+gimp_image_map_sync_mask (GimpImageMap *image_map)
+{
+  GimpImage   *image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
+  GimpChannel *mask  = gimp_image_get_mask (image);
 
-      /*  don't let the filter affect the drawable projection's alpha,
-       *  because it can't affect the drawable buffer's alpha either
-       *  when finally merged (see bug #699279)
-       */
-      if (! gimp_drawable_has_alpha (image_map->drawable))
-        active_mask &= ~GIMP_COMPONENT_MASK_ALPHA;
+  if (gimp_channel_is_empty (mask))
+    {
+      gimp_applicator_set_mask_buffer (image_map->applicator, NULL);
+    }
+  else
+    {
+      GeglBuffer *mask_buffer;
+      gint        offset_x, offset_y;
 
-      gimp_applicator_set_affect (image_map->applicator, active_mask);
+      mask_buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask));
+      gimp_item_get_offset (GIMP_ITEM (image_map->drawable),
+                            &offset_x, &offset_y);
+
+      gimp_applicator_set_mask_buffer (image_map->applicator, mask_buffer);
+      gimp_applicator_set_mask_offset (image_map->applicator,
+                                       -offset_x, -offset_y);
     }
 }
 
 static void
 gimp_image_map_sync_gamma_hack (GimpImageMap *image_map)
 {
-  if (image_map->applicator)
+  if (image_map->gamma_hack)
     {
-      if (image_map->gamma_hack)
-        {
-          const Babl *drawable_format;
-          const Babl *cast_format;
-
-          drawable_format =
-            gimp_drawable_get_format_with_alpha (image_map->drawable);
-
-          cast_format =
-            gimp_babl_format (gimp_babl_format_get_base_type (drawable_format),
-                              gimp_babl_precision (gimp_babl_format_get_component_type (drawable_format),
-                                                   ! gimp_babl_format_get_linear (drawable_format)),
-                              TRUE);
-
-          gegl_node_set (image_map->cast_before,
-                         "operation",     "gegl:cast-format",
-                         "input-format",  drawable_format,
-                         "output-format", cast_format,
-                         NULL);
-
-          gegl_node_set (image_map->cast_after,
-                         "operation",     "gegl:cast-format",
-                         "input-format",  cast_format,
-                         "output-format", drawable_format,
-                         NULL);
-        }
-      else
-        {
-          gegl_node_set (image_map->cast_before,
-                         "operation", "gegl:nop",
-                         NULL);
+      const Babl *drawable_format;
+      const Babl *cast_format;
+
+      drawable_format =
+        gimp_drawable_get_format_with_alpha (image_map->drawable);
+
+      cast_format =
+        gimp_babl_format (gimp_babl_format_get_base_type (drawable_format),
+                          gimp_babl_precision (gimp_babl_format_get_component_type (drawable_format),
+                                               ! gimp_babl_format_get_linear (drawable_format)),
+                          TRUE);
+
+      gegl_node_set (image_map->cast_before,
+                     "operation",     "gegl:cast-format",
+                     "input-format",  drawable_format,
+                     "output-format", cast_format,
+                     NULL);
+
+      gegl_node_set (image_map->cast_after,
+                     "operation",     "gegl:cast-format",
+                     "input-format",  cast_format,
+                     "output-format", drawable_format,
+                     NULL);
+    }
+  else
+    {
+      gegl_node_set (image_map->cast_before,
+                     "operation", "gegl:nop",
+                     NULL);
 
-          gegl_node_set (image_map->cast_after,
-                         "operation", "gegl:nop",
-                         NULL);
-        }
+      gegl_node_set (image_map->cast_after,
+                     "operation", "gegl:nop",
+                     NULL);
     }
 }
 
 static gboolean
 gimp_image_map_is_filtering (GimpImageMap *image_map)
 {
-  if (image_map->filter &&
-      gimp_drawable_has_filter (image_map->drawable, image_map->filter))
-    {
-      return TRUE;
-    }
-
-  return FALSE;
+  return gimp_drawable_has_filter (image_map->drawable,
+                                   GIMP_FILTER (image_map));
 }
 
 static gboolean
@@ -724,20 +670,29 @@ gimp_image_map_add_filter (GimpImageMap *image_map)
 {
   if (! gimp_image_map_is_filtering (image_map))
     {
-      if (image_map->filter)
-        {
-          GimpImage *image;
+      GimpImage *image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
 
-          gimp_drawable_add_filter (image_map->drawable, image_map->filter);
+      gimp_image_map_sync_region (image_map);
+      gimp_image_map_sync_preview (image_map,
+                                   image_map->preview_enabled,
+                                   image_map->preview_alignment,
+                                   image_map->preview_position);
+      gimp_image_map_sync_mode (image_map);
+      gimp_image_map_sync_affect (image_map);
+      gimp_image_map_sync_mask (image_map);
+      gimp_image_map_sync_gamma_hack (image_map);
 
-          image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
+      gimp_drawable_add_filter (image_map->drawable,
+                                GIMP_FILTER (image_map));
 
-          g_signal_connect (image, "component-active-changed",
-                            G_CALLBACK (gimp_image_map_affect_changed),
-                            image_map);
+      g_signal_connect (image, "component-active-changed",
+                        G_CALLBACK (gimp_image_map_affect_changed),
+                        image_map);
+      g_signal_connect (image, "mask-changed",
+                        G_CALLBACK (gimp_image_map_mask_changed),
+                        image_map);
 
-          return TRUE;
-        }
+      return TRUE;
     }
 
   return FALSE;
@@ -751,10 +706,14 @@ gimp_image_map_remove_filter (GimpImageMap *image_map)
       GimpImage *image = gimp_item_get_image (GIMP_ITEM (image_map->drawable));
 
       g_signal_handlers_disconnect_by_func (image,
+                                            gimp_image_map_mask_changed,
+                                            image_map);
+      g_signal_handlers_disconnect_by_func (image,
                                             gimp_image_map_affect_changed,
                                             image_map);
 
-      gimp_drawable_remove_filter (image_map->drawable, image_map->filter);
+      gimp_drawable_remove_filter (image_map->drawable,
+                                   GIMP_FILTER (image_map));
 
       return TRUE;
     }
@@ -766,13 +725,20 @@ static void
 gimp_image_map_update_drawable (GimpImageMap        *image_map,
                                 const GeglRectangle *area)
 {
-  gimp_drawable_update (image_map->drawable,
-                        area->x,
-                        area->y,
-                        area->width,
-                        area->height);
+  if (! area)
+    area = &image_map->filter_area;
+
+  if (area->width  > 0 &&
+      area->height > 0)
+    {
+      gimp_drawable_update (image_map->drawable,
+                            area->x,
+                            area->y,
+                            area->width,
+                            area->height);
 
-  g_signal_emit (image_map, image_map_signals[FLUSH], 0);
+      g_signal_emit (image_map, image_map_signals[FLUSH], 0);
+    }
 }
 
 static void
@@ -781,5 +747,24 @@ gimp_image_map_affect_changed (GimpImage       *image,
                                GimpImageMap    *image_map)
 {
   gimp_image_map_sync_affect (image_map);
-  gimp_image_map_update_drawable (image_map, &image_map->filter_area);
+  gimp_image_map_update_drawable (image_map, NULL);
+}
+
+static void
+gimp_image_map_mask_changed (GimpImage    *image,
+                             GimpImageMap *image_map)
+{
+  gimp_image_map_update_drawable (image_map, NULL);
+
+  gimp_image_map_sync_mask (image_map);
+
+  gimp_item_mask_intersect (GIMP_ITEM (image_map->drawable),
+                            &image_map->filter_area.x,
+                            &image_map->filter_area.y,
+                            &image_map->filter_area.width,
+                            &image_map->filter_area.height);
+
+  gimp_image_map_sync_region (image_map);
+
+  gimp_image_map_update_drawable (image_map, NULL);
 }
diff --git a/app/core/gimpimagemap.h b/app/core/gimpimagemap.h
index 7b4441d..a9b341b 100644
--- a/app/core/gimpimagemap.h
+++ b/app/core/gimpimagemap.h
@@ -19,7 +19,7 @@
 #define __GIMP_IMAGE_MAP_H__
 
 
-#include "gimpobject.h"
+#include "gimpfilter.h"
 
 
 #define GIMP_TYPE_IMAGE_MAP            (gimp_image_map_get_type ())
@@ -34,7 +34,7 @@ typedef struct _GimpImageMapClass  GimpImageMapClass;
 
 struct _GimpImageMapClass
 {
-  GimpObjectClass  parent_class;
+  GimpFilterClass  parent_class;
 
   void (* flush) (GimpImageMap *image_map);
 };
diff --git a/app/tools/gimpimagemaptool.c b/app/tools/gimpimagemaptool.c
index f482c13..d7b7e4e 100644
--- a/app/tools/gimpimagemaptool.c
+++ b/app/tools/gimpimagemaptool.c
@@ -203,7 +203,6 @@ gimp_image_map_tool_init (GimpImageMapTool *im_tool)
                                      GIMP_DIRTY_IMAGE           |
                                      GIMP_DIRTY_IMAGE_STRUCTURE |
                                      GIMP_DIRTY_DRAWABLE        |
-                                     GIMP_DIRTY_SELECTION       |
                                      GIMP_DIRTY_ACTIVE_DRAWABLE);
 }
 


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