[gimp] Bug 675747 - Layers with some modes get hidden in layer groups



commit c914aa805dc9de0157c10019d97fe64b564fe5d0
Author: Michael Natterer <mitch gimp org>
Date:   Mon Nov 12 10:55:41 2012 +0100

    Bug 675747 - Layers with some modes get hidden in layer groups
    
    Add a boolean "is-last-node" property to GimpDrawable and set it from
    GimpDrawableStack, which is the place that easily has the information.
    In GimpLayer, connect to "notify" and make sure we use NORMAL mode
    unless the layer is in NORMAL or DISSOLVE mode.

 app/core/gimpdrawable-private.h |    2 +
 app/core/gimpdrawable.c         |   84 +++++++++++++++++++++++++++++++++++++++
 app/core/gimpdrawable.h         |    4 ++
 app/core/gimpdrawablestack.c    |   21 ++++++++--
 app/core/gimplayer.c            |   46 ++++++++++++++++++++-
 5 files changed, 150 insertions(+), 7 deletions(-)
---
diff --git a/app/core/gimpdrawable-private.h b/app/core/gimpdrawable-private.h
index bfe9d38..b7b8754 100644
--- a/app/core/gimpdrawable-private.h
+++ b/app/core/gimpdrawable-private.h
@@ -32,6 +32,8 @@ struct _GimpDrawablePrivate
   GeglNode      *fs_mode_node;
 
   GeglNode      *mode_node;
+
+  gboolean       is_last_node;
 };
 
 #endif /* __GIMP_DRAWABLE_PRIVATE_H__ */
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 28b4fc1..b34852e 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -61,6 +61,12 @@ enum
   LAST_SIGNAL
 };
 
+enum
+{
+  PROP_0,
+  PROP_IS_LAST_NODE
+};
+
 
 /*  local function prototypes  */
 
@@ -68,6 +74,14 @@ static void  gimp_drawable_pickable_iface_init (GimpPickableInterface *iface);
 
 static void       gimp_drawable_dispose            (GObject           *object);
 static void       gimp_drawable_finalize           (GObject           *object);
+static void       gimp_drawable_set_property       (GObject           *object,
+                                                    guint              property_id,
+                                                    const GValue      *value,
+                                                    GParamSpec        *pspec);
+static void       gimp_drawable_get_property       (GObject           *object,
+                                                    guint              property_id,
+                                                    GValue            *value,
+                                                    GParamSpec        *pspec);
 
 static gint64     gimp_drawable_get_memsize        (GimpObject        *object,
                                                     gint64            *gui_size);
@@ -212,6 +226,8 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
 
   object_class->dispose              = gimp_drawable_dispose;
   object_class->finalize             = gimp_drawable_finalize;
+  object_class->set_property         = gimp_drawable_set_property;
+  object_class->get_property         = gimp_drawable_get_property;
 
   gimp_object_class->get_memsize     = gimp_drawable_get_memsize;
 
@@ -242,6 +258,12 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
   klass->push_undo                   = gimp_drawable_real_push_undo;
   klass->swap_pixels                 = gimp_drawable_real_swap_pixels;
 
+  g_object_class_install_property (object_class, PROP_IS_LAST_NODE,
+                                   g_param_spec_boolean ("is-last-node",
+                                                         NULL, NULL,
+                                                         FALSE,
+                                                         GIMP_PARAM_READWRITE));
+
   g_type_class_add_private (klass, sizeof (GimpDrawablePrivate));
 }
 
@@ -298,6 +320,46 @@ gimp_drawable_finalize (GObject *object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static void
+gimp_drawable_set_property (GObject      *object,
+                            guint         property_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+  GimpDrawable *drawable = GIMP_DRAWABLE (object);
+
+  switch (property_id)
+    {
+    case PROP_IS_LAST_NODE:
+      drawable->private->is_last_node = g_value_get_boolean (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_drawable_get_property (GObject    *object,
+                            guint       property_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+  GimpDrawable *drawable = GIMP_DRAWABLE (object);
+
+  switch (property_id)
+    {
+    case PROP_IS_LAST_NODE:
+      g_value_set_boolean (value, drawable->private->is_last_node);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
 static gint64
 gimp_drawable_get_memsize (GimpObject *object,
                            gint64     *gui_size)
@@ -1319,6 +1381,28 @@ gimp_drawable_get_mode_node (GimpDrawable *drawable)
 }
 
 void
+gimp_drawable_set_is_last_node (GimpDrawable *drawable,
+                                gboolean      last_node)
+{
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+
+  if (last_node != drawable->private->is_last_node)
+    {
+      g_object_set (drawable,
+                    "is-last-node", last_node ? TRUE : FALSE,
+                    NULL);
+    }
+}
+
+gboolean
+gimp_drawable_get_is_last_node (GimpDrawable *drawable)
+{
+  g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
+
+  return drawable->private->is_last_node;
+}
+
+void
 gimp_drawable_swap_pixels (GimpDrawable *drawable,
                            GeglBuffer   *buffer,
                            gint          x,
diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h
index 06485cb..339a6b8 100644
--- a/app/core/gimpdrawable.h
+++ b/app/core/gimpdrawable.h
@@ -180,6 +180,10 @@ void            gimp_drawable_set_buffer_full    (GimpDrawable       *drawable,
 GeglNode      * gimp_drawable_get_source_node    (GimpDrawable       *drawable);
 GeglNode      * gimp_drawable_get_mode_node      (GimpDrawable       *drawable);
 
+void            gimp_drawable_set_is_last_node   (GimpDrawable       *drawable,
+                                                  gboolean            last_node);
+gboolean        gimp_drawable_get_is_last_node   (GimpDrawable       *drawable);
+
 void            gimp_drawable_swap_pixels        (GimpDrawable       *drawable,
                                                   GeglBuffer         *buffer,
                                                   gint                x,
diff --git a/app/core/gimpdrawablestack.c b/app/core/gimpdrawablestack.c
index 0d12a1f..33b86a4 100644
--- a/app/core/gimpdrawablestack.c
+++ b/app/core/gimpdrawablestack.c
@@ -235,6 +235,9 @@ gimp_drawable_stack_get_graph (GimpDrawableStack *stack)
       GimpDrawable *drawable = list->data;
 
       reverse_list = g_list_prepend (reverse_list, drawable);
+
+      if (! g_list_next (list))
+        gimp_drawable_set_is_last_node (drawable, TRUE);
     }
 
   stack->graph = gegl_node_new ();
@@ -271,6 +274,7 @@ static void
 gimp_drawable_stack_add_node (GimpDrawableStack *stack,
                               GimpDrawable      *drawable)
 {
+  GimpDrawable *drawable_above = NULL;
   GimpDrawable *drawable_below;
   GeglNode     *node_above;
   GeglNode     *node;
@@ -287,8 +291,6 @@ gimp_drawable_stack_add_node (GimpDrawableStack *stack,
     }
   else
     {
-      GimpDrawable *drawable_above;
-
       drawable_above = (GimpDrawable *)
         gimp_container_get_child_by_index (GIMP_CONTAINER (stack), index - 1);
 
@@ -308,12 +310,20 @@ gimp_drawable_stack_add_node (GimpDrawableStack *stack,
       gegl_node_connect_to (node_below, "output",
                             node,       "input");
     }
+  else
+    {
+      if (drawable_above)
+        gimp_drawable_set_is_last_node (drawable_above, FALSE);
+
+      gimp_drawable_set_is_last_node (drawable, TRUE);
+    }
 }
 
 static void
 gimp_drawable_stack_remove_node (GimpDrawableStack *stack,
                                  GimpDrawable      *drawable)
 {
+  GimpDrawable *drawable_above = NULL;
   GimpDrawable *drawable_below;
   GeglNode     *node_above;
   GeglNode     *node;
@@ -330,8 +340,6 @@ gimp_drawable_stack_remove_node (GimpDrawableStack *stack,
     }
   else
     {
-      GimpDrawable *drawable_above;
-
       drawable_above = (GimpDrawable *)
         gimp_container_get_child_by_index (GIMP_CONTAINER (stack), index - 1);
 
@@ -352,6 +360,11 @@ gimp_drawable_stack_remove_node (GimpDrawableStack *stack,
   else
     {
       gegl_node_disconnect (node_above, "input");
+
+      gimp_drawable_set_is_last_node (drawable, FALSE);
+
+      if (drawable_above)
+        gimp_drawable_set_is_last_node (drawable_above, TRUE);
     }
 }
 
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index 2525d20..1329577 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -85,6 +85,8 @@ static void       gimp_layer_get_property       (GObject            *object,
                                                  GParamSpec         *pspec);
 static void       gimp_layer_dispose            (GObject            *object);
 static void       gimp_layer_finalize           (GObject            *object);
+static void       gimp_layer_notify             (GObject            *object,
+                                                 GParamSpec         *pspec);
 
 static void       gimp_layer_name_changed       (GimpObject         *object);
 static gint64     gimp_layer_get_memsize        (GimpObject         *object,
@@ -264,6 +266,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
   object_class->get_property          = gimp_layer_get_property;
   object_class->dispose               = gimp_layer_dispose;
   object_class->finalize              = gimp_layer_finalize;
+  object_class->notify                = gimp_layer_notify;
 
   gimp_object_class->name_changed     = gimp_layer_name_changed;
   gimp_object_class->get_memsize      = gimp_layer_get_memsize;
@@ -466,6 +469,39 @@ gimp_layer_finalize (GObject *object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static GimpLayerModeEffects
+gimp_layer_get_visible_mode (GimpLayer *layer)
+{
+  if (layer->mode != GIMP_DISSOLVE_MODE &&
+      gimp_drawable_get_is_last_node (GIMP_DRAWABLE (layer)))
+    return GIMP_NORMAL_MODE;
+
+  return layer->mode;
+}
+
+static void
+gimp_layer_notify (GObject    *object,
+                   GParamSpec *pspec)
+{
+  if (! strcmp (pspec->name, "is-last-node") &&
+      gimp_item_peek_node (GIMP_ITEM (object)))
+    {
+      GimpLayer *layer = GIMP_LAYER (object);
+      GeglNode  *mode_node;
+
+      mode_node = gimp_drawable_get_mode_node (GIMP_DRAWABLE (layer));
+
+      gimp_gegl_mode_node_set (mode_node,
+                               gimp_layer_get_visible_mode (layer),
+                               layer->opacity, FALSE);
+
+      gimp_drawable_update (GIMP_DRAWABLE (layer),
+                            0, 0,
+                            gimp_item_get_width  (GIMP_ITEM (layer)),
+                            gimp_item_get_height (GIMP_ITEM (layer)));
+    }
+}
+
 static void
 gimp_layer_name_changed (GimpObject *object)
 {
@@ -880,7 +916,9 @@ gimp_layer_get_node (GimpItem *item)
    */
   mode_node = gimp_drawable_get_mode_node (drawable);
 
-  gimp_gegl_mode_node_set (mode_node, layer->mode, layer->opacity, FALSE);
+  gimp_gegl_mode_node_set (mode_node,
+                           gimp_layer_get_visible_mode (layer),
+                           layer->opacity, FALSE);
 
   /* the layer's offset node */
   layer->layer_offset_node = gegl_node_new_child (node,
@@ -1944,7 +1982,8 @@ gimp_layer_set_opacity (GimpLayer *layer,
           mode_node = gimp_drawable_get_mode_node (GIMP_DRAWABLE (layer));
 
           gimp_gegl_mode_node_set (mode_node,
-                                   layer->mode, layer->opacity, FALSE);
+                                   gimp_layer_get_visible_mode (layer),
+                                   layer->opacity, FALSE);
         }
 
       gimp_drawable_update (GIMP_DRAWABLE (layer),
@@ -1990,7 +2029,8 @@ gimp_layer_set_mode (GimpLayer            *layer,
           mode_node = gimp_drawable_get_mode_node (GIMP_DRAWABLE (layer));
 
           gimp_gegl_mode_node_set (mode_node,
-                                   layer->mode, layer->opacity, FALSE);
+                                   gimp_layer_get_visible_mode (layer),
+                                   layer->opacity, FALSE);
         }
 
       gimp_drawable_update (GIMP_DRAWABLE (layer),



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