[gimp/wip/passthrough: 559/565] app: handle excludes_backdrop in GimpGroupLayer



commit 70c1ca5d38c9e0e35c65c988197c6e64459ca9ce
Author: Ell <ell_se yahoo com>
Date:   Mon May 8 15:06:00 2017 -0400

    app: handle excludes_backdrop in GimpGroupLayer
    
    When any of the children of a pass-through group excludes its
    backdrop, the group itself should exclude the backdrop too.  Override
    get_excludes_backdrop() to follow this logic, and call
    update_excludes_backdrop() when this condition might change.
    
    Note that we always composite pass-through groups using src-over mode,
    so to actually hide the backdrop, we need to disconnect it from the
    group's mode node's input pad (and reconnect it, when the backdrop is
    no longer hidden).

 app/core/gimpdrawable.c   |   12 +--
 app/core/gimpgrouplayer.c |  180 ++++++++++++++++++++++++++++++++++++---------
 2 files changed, 148 insertions(+), 44 deletions(-)
---
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index bee7a2e..1c66584 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -400,21 +400,16 @@ gimp_drawable_visibility_changed (GimpFilter *filter)
 
   if (node)
     {
-      GeglNode *input  = gegl_node_get_input_proxy  (node, "input");
       GeglNode *output = gegl_node_get_output_proxy (node, "output");
 
       if (gimp_filter_get_visible (filter))
         {
-          gegl_node_connect_to (input,                        "output",
-                                drawable->private->mode_node, "input");
           gegl_node_connect_to (drawable->private->mode_node, "output",
                                 output,                       "input");
         }
       else
         {
-          gegl_node_disconnect (drawable->private->mode_node, "input");
-
-          /* The rest handled by GimpFilter */
+          /* Handled by GimpFilter */
         }
     }
 
@@ -441,10 +436,11 @@ gimp_drawable_get_node (GimpFilter *filter)
   input  = gegl_node_get_input_proxy  (node, "input");
   output = gegl_node_get_output_proxy (node, "output");
 
+  gegl_node_connect_to (input,                        "output",
+                        drawable->private->mode_node, "input");
+
   if (gimp_filter_get_visible (filter))
     {
-      gegl_node_connect_to (input,                        "output",
-                            drawable->private->mode_node, "input");
       gegl_node_connect_to (drawable->private->mode_node, "output",
                             output,                       "input");
     }
diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c
index 881556f..eea5759 100644
--- a/app/core/gimpgrouplayer.c
+++ b/app/core/gimpgrouplayer.c
@@ -150,6 +150,10 @@ static void            gimp_group_layer_convert_type (GimpLayer         *layer,
 static GeglNode   * gimp_group_layer_get_source_node (GimpDrawable      *drawable);
 
 static void            gimp_group_layer_mode_changed (GimpLayer         *layer);
+static void
+          gimp_group_layer_excludes_backdrop_changed (GimpLayer         *layer);
+static gboolean
+              gimp_group_layer_get_excludes_backdrop (GimpLayer         *layer);
 
 static const Babl    * gimp_group_layer_get_format   (GimpProjectable *projectable);
 static GeglNode      * gimp_group_layer_get_graph    (GimpProjectable *projectable);
@@ -169,10 +173,17 @@ static void            gimp_group_layer_child_move   (GimpLayer       *child,
                                                       GimpGroupLayer  *group);
 static void            gimp_group_layer_child_resize (GimpLayer       *child,
                                                       GimpGroupLayer  *group);
+static void
+           gimp_group_layer_child_visibility_changed (GimpLayer       *child,
+                                                      GimpGroupLayer  *group);
+static void
+    gimp_group_layer_child_excludes_backdrop_changed (GimpLayer       *child,
+                                                      GimpGroupLayer  *group);
 
 static void            gimp_group_layer_update       (GimpGroupLayer  *group);
 static void            gimp_group_layer_update_size  (GimpGroupLayer  *group);
 static void      gimp_group_layer_update_source_node (GimpGroupLayer  *group);
+static void        gimp_group_layer_update_mode_node (GimpGroupLayer  *group);
 
 static void            gimp_group_layer_stack_update (GimpDrawableStack *stack,
                                                       gint               x,
@@ -209,42 +220,44 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
   GimpDrawableClass *drawable_class    = GIMP_DRAWABLE_CLASS (klass);
   GimpLayerClass    *layer_class       = GIMP_LAYER_CLASS (klass);
 
-  object_class->set_property        = gimp_group_layer_set_property;
-  object_class->get_property        = gimp_group_layer_get_property;
-  object_class->finalize            = gimp_group_layer_finalize;
-
-  gimp_object_class->get_memsize    = gimp_group_layer_get_memsize;
-
-  viewable_class->default_icon_name = "gimp-group-layer";
-  viewable_class->get_size          = gimp_group_layer_get_size;
-  viewable_class->get_children      = gimp_group_layer_get_children;
-  viewable_class->set_expanded      = gimp_group_layer_set_expanded;
-  viewable_class->get_expanded      = gimp_group_layer_get_expanded;
-
-  item_class->is_position_locked    = gimp_group_layer_is_position_locked;
-  item_class->duplicate             = gimp_group_layer_duplicate;
-  item_class->convert               = gimp_group_layer_convert;
-
-  item_class->default_name          = _("Layer Group");
-  item_class->rename_desc           = C_("undo-type", "Rename Layer Group");
-  item_class->translate_desc        = C_("undo-type", "Move Layer Group");
-  item_class->scale_desc            = C_("undo-type", "Scale Layer Group");
-  item_class->resize_desc           = C_("undo-type", "Resize Layer Group");
-  item_class->flip_desc             = C_("undo-type", "Flip Layer Group");
-  item_class->rotate_desc           = C_("undo-type", "Rotate Layer Group");
-  item_class->transform_desc        = C_("undo-type", "Transform Layer Group");
-
-  drawable_class->estimate_memsize  = gimp_group_layer_estimate_memsize;
-  drawable_class->get_source_node   = gimp_group_layer_get_source_node;
-
-  layer_class->mode_changed         = gimp_group_layer_mode_changed;
-  layer_class->translate            = gimp_group_layer_translate;
-  layer_class->scale                = gimp_group_layer_scale;
-  layer_class->resize               = gimp_group_layer_resize;
-  layer_class->flip                 = gimp_group_layer_flip;
-  layer_class->rotate               = gimp_group_layer_rotate;
-  layer_class->transform            = gimp_group_layer_transform;
-  layer_class->convert_type         = gimp_group_layer_convert_type;
+  object_class->set_property             = gimp_group_layer_set_property;
+  object_class->get_property             = gimp_group_layer_get_property;
+  object_class->finalize                 = gimp_group_layer_finalize;
+
+  gimp_object_class->get_memsize         = gimp_group_layer_get_memsize;
+
+  viewable_class->default_icon_name      = "gimp-group-layer";
+  viewable_class->get_size               = gimp_group_layer_get_size;
+  viewable_class->get_children           = gimp_group_layer_get_children;
+  viewable_class->set_expanded           = gimp_group_layer_set_expanded;
+  viewable_class->get_expanded           = gimp_group_layer_get_expanded;
+
+  item_class->is_position_locked         = gimp_group_layer_is_position_locked;
+  item_class->duplicate                  = gimp_group_layer_duplicate;
+  item_class->convert                    = gimp_group_layer_convert;
+
+  item_class->default_name               = _("Layer Group");
+  item_class->rename_desc                = C_("undo-type", "Rename Layer Group");
+  item_class->translate_desc             = C_("undo-type", "Move Layer Group");
+  item_class->scale_desc                 = C_("undo-type", "Scale Layer Group");
+  item_class->resize_desc                = C_("undo-type", "Resize Layer Group");
+  item_class->flip_desc                  = C_("undo-type", "Flip Layer Group");
+  item_class->rotate_desc                = C_("undo-type", "Rotate Layer Group");
+  item_class->transform_desc             = C_("undo-type", "Transform Layer Group");
+
+  drawable_class->estimate_memsize       = gimp_group_layer_estimate_memsize;
+  drawable_class->get_source_node        = gimp_group_layer_get_source_node;
+
+  layer_class->mode_changed              = gimp_group_layer_mode_changed;
+  layer_class->excludes_backdrop_changed = gimp_group_layer_excludes_backdrop_changed;
+  layer_class->translate                 = gimp_group_layer_translate;
+  layer_class->scale                     = gimp_group_layer_scale;
+  layer_class->resize                    = gimp_group_layer_resize;
+  layer_class->flip                      = gimp_group_layer_flip;
+  layer_class->rotate                    = gimp_group_layer_rotate;
+  layer_class->transform                 = gimp_group_layer_transform;
+  layer_class->convert_type              = gimp_group_layer_convert_type;
+  layer_class->get_excludes_backdrop     = gimp_group_layer_get_excludes_backdrop;
 
   g_type_class_add_private (klass, sizeof (GimpGroupLayerPrivate));
 }
@@ -290,6 +303,12 @@ gimp_group_layer_init (GimpGroupLayer *group)
   gimp_container_add_handler (private->children, "size-changed",
                               G_CALLBACK (gimp_group_layer_child_resize),
                               group);
+  gimp_container_add_handler (private->children, "visibility-changed",
+                              G_CALLBACK (gimp_group_layer_child_visibility_changed),
+                              group);
+  gimp_container_add_handler (private->children, "excludes-backdrop-changed",
+                              G_CALLBACK (gimp_group_layer_child_excludes_backdrop_changed),
+                              group);
 
   g_signal_connect (private->children, "update",
                     G_CALLBACK (gimp_group_layer_stack_update),
@@ -916,11 +935,49 @@ gimp_group_layer_mode_changed (GimpLayer *layer)
   GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
 
   gimp_group_layer_update_source_node (group);
+  gimp_group_layer_update_mode_node (group);
 
   if (GIMP_LAYER_CLASS (parent_class)->mode_changed)
     GIMP_LAYER_CLASS (parent_class)->mode_changed (layer);
 }
 
+static void
+gimp_group_layer_excludes_backdrop_changed (GimpLayer *layer)
+{
+  GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+
+  gimp_group_layer_update_source_node (group);
+  gimp_group_layer_update_mode_node (group);
+
+  if (GIMP_LAYER_CLASS (parent_class)->excludes_backdrop_changed)
+    GIMP_LAYER_CLASS (parent_class)->excludes_backdrop_changed (layer);
+}
+
+static gboolean
+gimp_group_layer_get_excludes_backdrop (GimpLayer *layer)
+{
+  if (gimp_layer_get_mode (layer) == GIMP_LAYER_MODE_PASS_THROUGH)
+    {
+      GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
+      GList                 *list;
+
+      for (list = gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (private->children));
+           list;
+           list = g_list_next (list))
+        {
+          GimpItem *child = list->data;
+
+          if (gimp_item_get_visible (child) &&
+              gimp_layer_get_excludes_backdrop (GIMP_LAYER (child)))
+            return TRUE;
+        }
+
+      return FALSE;
+    }
+  else
+    return GIMP_LAYER_CLASS (parent_class)->get_excludes_backdrop (layer);
+}
+
 static const Babl *
 gimp_group_layer_get_format (GimpProjectable *projectable)
 {
@@ -1080,6 +1137,12 @@ gimp_group_layer_child_add (GimpContainer  *container,
                             GimpGroupLayer *group)
 {
   gimp_group_layer_update (group);
+
+  if (gimp_item_get_visible (GIMP_ITEM (child)) &&
+      gimp_layer_get_excludes_backdrop (child))
+    {
+      gimp_layer_update_excludes_backdrop (GIMP_LAYER (group));
+    }
 }
 
 static void
@@ -1088,6 +1151,12 @@ gimp_group_layer_child_remove (GimpContainer  *container,
                                GimpGroupLayer *group)
 {
   gimp_group_layer_update (group);
+
+  if (gimp_item_get_visible (GIMP_ITEM (child)) &&
+      gimp_layer_get_excludes_backdrop (child))
+    {
+      gimp_layer_update_excludes_backdrop (GIMP_LAYER (group));
+    }
 }
 
 static void
@@ -1106,6 +1175,22 @@ gimp_group_layer_child_resize (GimpLayer      *child,
 }
 
 static void
+gimp_group_layer_child_visibility_changed (GimpLayer      *child,
+                                           GimpGroupLayer *group)
+{
+  if (gimp_layer_get_excludes_backdrop (child))
+    gimp_layer_update_excludes_backdrop (GIMP_LAYER (group));
+}
+
+static void
+gimp_group_layer_child_excludes_backdrop_changed (GimpLayer      *child,
+                                                  GimpGroupLayer *group)
+{
+  if (gimp_item_get_visible (GIMP_ITEM (child)))
+    gimp_layer_update_excludes_backdrop (GIMP_LAYER (group));
+}
+
+static void
 gimp_group_layer_update (GimpGroupLayer *group)
 {
   if (GET_PRIVATE (group)->suspend_resize == 0)
@@ -1258,6 +1343,29 @@ gimp_group_layer_update_source_node (GimpGroupLayer *group)
 }
 
 static void
+gimp_group_layer_update_mode_node (GimpGroupLayer *group)
+{
+  GeglNode *node;
+  GeglNode *input;
+  GeglNode *mode_node;
+
+  node      = gimp_filter_get_node (GIMP_FILTER (group));
+  input     = gegl_node_get_input_proxy (node, "input");
+  mode_node = gimp_drawable_get_mode_node (GIMP_DRAWABLE (group));
+
+  if (gimp_layer_get_mode (GIMP_LAYER (group)) == GIMP_LAYER_MODE_PASS_THROUGH &&
+      gimp_layer_get_excludes_backdrop (GIMP_LAYER (group)))
+    {
+      gegl_node_disconnect (mode_node, "input");
+    }
+  else
+    {
+      gegl_node_connect_to (input,     "output",
+                            mode_node, "input");
+    }
+}
+
+static void
 gimp_group_layer_stack_update (GimpDrawableStack *stack,
                                gint               x,
                                gint               y,


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