[gimp] Add "active-item" property and API to GimpItemTree



commit c9645cc0d39538cdc270b0d21f5e8deb5d4bfb01
Author: Michael Natterer <mitch gimp org>
Date:   Sun Feb 7 14:52:34 2010 +0100

    Add "active-item" property and API to GimpItemTree
    
    and use it to store the image's active layer, channel and vectors.

 app/core/gimpimage-private.h |    4 ---
 app/core/gimpimage.c         |   59 +++++++++++++++++++++++++-----------------
 app/core/gimpitemtree.c      |   49 ++++++++++++++++++++++++++++++++++-
 app/core/gimpitemtree.h      |   55 +++++++++++++++++++++-----------------
 4 files changed, 113 insertions(+), 54 deletions(-)
---
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index 13bbf4e..92e5aed 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -78,10 +78,6 @@ struct _GimpImagePrivate
   GQuark             channel_name_changed_handler;
   GQuark             channel_color_changed_handler;
 
-  GimpLayer         *active_layer;          /*  the active layer             */
-  GimpChannel       *active_channel;        /*  the active channel           */
-  GimpVectors       *active_vectors;        /*  the active vectors           */
-
   GimpLayer         *floating_sel;          /*  the FS layer                 */
   GimpChannel       *selection_mask;        /*  the selection mask channel   */
 
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index fe014ed..0e8d6b3 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -659,10 +659,6 @@ gimp_image_init (GimpImage *image)
                     G_CALLBACK (gimp_image_channel_remove),
                     image);
 
-  private->active_layer        = NULL;
-  private->active_channel      = NULL;
-  private->active_vectors      = NULL;
-
   private->floating_sel        = NULL;
   private->selection_mask      = NULL;
 
@@ -2985,21 +2981,26 @@ GimpDrawable *
 gimp_image_get_active_drawable (const GimpImage *image)
 {
   GimpImagePrivate *private;
+  GimpItem         *active_channel;
+  GimpItem         *active_layer;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
   private = GIMP_IMAGE_GET_PRIVATE (image);
 
+  active_channel = gimp_item_tree_get_active_item (private->channels);
+  active_layer   = gimp_item_tree_get_active_item (private->layers);
+
   /*  If there is an active channel (a saved selection, etc.),
    *  we ignore the active layer
    */
-  if (private->active_channel)
+  if (active_channel)
     {
-      return GIMP_DRAWABLE (private->active_channel);
+      return GIMP_DRAWABLE (active_channel);
     }
-  else if (private->active_layer)
+  else if (active_layer)
     {
-      GimpLayer     *layer = private->active_layer;
+      GimpLayer     *layer = GIMP_LAYER (active_layer);
       GimpLayerMask *mask  = gimp_layer_get_mask (layer);
 
       if (mask && gimp_layer_mask_get_edit (mask))
@@ -3016,7 +3017,7 @@ gimp_image_get_active_layer (const GimpImage *image)
 {
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
-  return GIMP_IMAGE_GET_PRIVATE (image)->active_layer;
+  return GIMP_LAYER (gimp_item_tree_get_active_item (GIMP_IMAGE_GET_PRIVATE (image)->layers));
 }
 
 GimpChannel *
@@ -3024,7 +3025,7 @@ gimp_image_get_active_channel (const GimpImage *image)
 {
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
-  return GIMP_IMAGE_GET_PRIVATE (image)->active_channel;
+  return GIMP_CHANNEL (gimp_item_tree_get_active_item (GIMP_IMAGE_GET_PRIVATE (image)->channels));
 }
 
 GimpVectors *
@@ -3032,7 +3033,7 @@ gimp_image_get_active_vectors (const GimpImage *image)
 {
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
-  return GIMP_IMAGE_GET_PRIVATE (image)->active_vectors;
+  return GIMP_VECTORS (gimp_item_tree_get_active_item (GIMP_IMAGE_GET_PRIVATE (image)->vectors));
 }
 
 GimpLayer *
@@ -3041,6 +3042,7 @@ gimp_image_set_active_layer (GimpImage *image,
 {
   GimpImagePrivate *private;
   GimpLayer        *floating_sel;
+  GimpLayer        *active_layer;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
   g_return_val_if_fail (layer == NULL || GIMP_IS_LAYER (layer), NULL);
@@ -3057,7 +3059,9 @@ gimp_image_set_active_layer (GimpImage *image,
   if (floating_sel && layer != floating_sel)
     return floating_sel;
 
-  if (layer != private->active_layer)
+  active_layer = gimp_image_get_active_layer (image);
+
+  if (layer != active_layer)
     {
       if (layer)
         {
@@ -3067,18 +3071,18 @@ gimp_image_set_active_layer (GimpImage *image,
         }
 
       /*  Don't cache selection info for the previous active layer  */
-      if (private->active_layer)
-        gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (private->active_layer));
+      if (active_layer)
+        gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (active_layer));
 
-      private->active_layer = layer;
+      gimp_item_tree_set_active_item (private->layers, GIMP_ITEM (layer));
 
       g_signal_emit (image, gimp_image_signals[ACTIVE_LAYER_CHANGED], 0);
 
-      if (layer && private->active_channel)
+      if (layer && gimp_image_get_active_channel (image))
         gimp_image_set_active_channel (image, NULL);
     }
 
-  return private->active_layer;
+  return gimp_image_get_active_layer (image);
 }
 
 GimpChannel *
@@ -3086,6 +3090,7 @@ gimp_image_set_active_channel (GimpImage   *image,
                                GimpChannel *channel)
 {
   GimpImagePrivate *private;
+  GimpChannel      *active_channel;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
   g_return_val_if_fail (channel == NULL || GIMP_IS_CHANNEL (channel), NULL);
@@ -3100,17 +3105,19 @@ gimp_image_set_active_channel (GimpImage   *image,
   if (channel && gimp_image_get_floating_selection (image))
     return NULL;
 
-  if (channel != private->active_channel)
+  active_channel = gimp_image_get_active_channel (image);
+
+  if (channel != active_channel)
     {
-      private->active_channel = channel;
+      gimp_item_tree_set_active_item (private->channels, GIMP_ITEM (channel));
 
       g_signal_emit (image, gimp_image_signals[ACTIVE_CHANNEL_CHANGED], 0);
 
-      if (channel && private->active_layer)
+      if (channel && gimp_image_get_active_layer (image))
         gimp_image_set_active_layer (image, NULL);
     }
 
-  return private->active_channel;
+  return gimp_image_get_active_channel (image);
 }
 
 GimpChannel *
@@ -3122,6 +3129,7 @@ gimp_image_unset_active_channel (GimpImage *image)
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
   private = GIMP_IMAGE_GET_PRIVATE (image);
+
   channel = gimp_image_get_active_channel (image);
 
   if (channel)
@@ -3140,6 +3148,7 @@ gimp_image_set_active_vectors (GimpImage   *image,
                                GimpVectors *vectors)
 {
   GimpImagePrivate *private;
+  GimpVectors      *active_vectors;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
   g_return_val_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors), NULL);
@@ -3150,14 +3159,16 @@ gimp_image_set_active_vectors (GimpImage   *image,
 
   private = GIMP_IMAGE_GET_PRIVATE (image);
 
-  if (vectors != private->active_vectors)
+  active_vectors = gimp_image_get_active_vectors (image);
+
+  if (vectors != active_vectors)
     {
-      private->active_vectors = vectors;
+      gimp_item_tree_set_active_item (private->vectors, GIMP_ITEM (vectors));
 
       g_signal_emit (image, gimp_image_signals[ACTIVE_VECTORS_CHANGED], 0);
     }
 
-  return private->active_vectors;
+  return gimp_image_get_active_vectors (image);
 }
 
 GimpLayer *
diff --git a/app/core/gimpitemtree.c b/app/core/gimpitemtree.c
index 64082f3..abdf04f 100644
--- a/app/core/gimpitemtree.c
+++ b/app/core/gimpitemtree.c
@@ -38,7 +38,8 @@ enum
   PROP_0,
   PROP_IMAGE,
   PROP_CONTAINER_TYPE,
-  PROP_ITEM_TYPE
+  PROP_ITEM_TYPE,
+  PROP_ACTIVE_ITEM
 };
 
 
@@ -47,8 +48,11 @@ typedef struct _GimpItemTreePrivate GimpItemTreePrivate;
 struct _GimpItemTreePrivate
 {
   GimpImage *image;
+
   GType      container_type;
   GType      item_type;
+
+  GimpItem  *active_item;
 };
 
 #define GIMP_ITEM_TREE_GET_PRIVATE(object) \
@@ -115,6 +119,12 @@ gimp_item_tree_class_init (GimpItemTreeClass *klass)
                                                        GIMP_PARAM_READWRITE |
                                                        G_PARAM_CONSTRUCT_ONLY));
 
+  g_object_class_install_property (object_class, PROP_ACTIVE_ITEM,
+                                   g_param_spec_object ("active-item",
+                                                        NULL, NULL,
+                                                        GIMP_TYPE_ITEM,
+                                                        GIMP_PARAM_READWRITE));
+
   g_type_class_add_private (klass, sizeof (GimpItemTreePrivate));
 }
 
@@ -185,6 +195,9 @@ gimp_item_tree_set_property (GObject      *object,
     case PROP_ITEM_TYPE:
       private->item_type = g_value_get_gtype (value);
       break;
+    case PROP_ACTIVE_ITEM:
+      private->active_item = g_value_get_object (value); /* don't ref */
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -211,6 +224,9 @@ gimp_item_tree_get_property (GObject    *object,
     case PROP_ITEM_TYPE:
       g_value_set_gtype (value, private->item_type);
       break;
+    case PROP_ACTIVE_ITEM:
+      g_value_set_object (value, private->active_item);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -251,6 +267,37 @@ gimp_item_tree_new (GimpImage *image,
 }
 
 GimpItem *
+gimp_item_tree_get_active_item (GimpItemTree *tree)
+{
+  g_return_val_if_fail (GIMP_IS_ITEM_TREE (tree), NULL);
+
+  return GIMP_ITEM_TREE_GET_PRIVATE (tree)->active_item;
+}
+
+void
+gimp_item_tree_set_active_item (GimpItemTree *tree,
+                                GimpItem     *item)
+{
+  GimpItemTreePrivate *private;
+
+  g_return_if_fail (GIMP_IS_ITEM_TREE (tree));
+  g_return_if_fail (item == NULL || GIMP_IS_ITEM (item));
+
+  private = GIMP_ITEM_TREE_GET_PRIVATE (tree);
+
+  g_return_if_fail (item == NULL ||
+                    (gimp_item_is_attached (item) &&
+                     gimp_item_get_image (item) == private->image));
+
+  if (item != private->active_item)
+    {
+      private->active_item = item;
+
+      g_object_notify (G_OBJECT (tree), "active-item");
+    }
+}
+
+GimpItem *
 gimp_item_tree_get_insert_pos (GimpItemTree   *tree,
                                GimpItem       *parent,
                                gint           *position,
diff --git a/app/core/gimpitemtree.h b/app/core/gimpitemtree.h
index fd2cea3..243d242 100644
--- a/app/core/gimpitemtree.h
+++ b/app/core/gimpitemtree.h
@@ -47,30 +47,35 @@ struct _GimpItemTreeClass
 };
 
 
-GType          gimp_item_tree_get_type       (void) G_GNUC_CONST;
-GimpItemTree * gimp_item_tree_new            (GimpImage    *image,
-                                              GType         container_type,
-                                              GType         item_type);
-
-GimpItem     * gimp_item_tree_get_insert_pos (GimpItemTree   *tree,
-                                              GimpItem       *parent,
-                                              gint           *position,
-                                              GimpItem       *active_item);
-
-void           gimp_item_tree_add_item       (GimpItemTree *tree,
-                                              GimpItem     *item,
-                                              GimpItem     *parent,
-                                              gint          position);
-GimpItem     * gimp_item_tree_remove_item    (GimpItemTree *tree,
-                                              GimpItem     *item,
-                                              GimpItem     *current_active,
-                                              GimpItem     *new_active);
-
-gboolean       gimp_item_tree_reorder_item   (GimpItemTree *tree,
-                                              GimpItem     *item,
-                                              GimpItem     *new_parent,
-                                              gint          new_index,
-                                              gboolean      push_undo,
-                                              const gchar  *undo_desc);
+GType          gimp_item_tree_get_type        (void) G_GNUC_CONST;
+GimpItemTree * gimp_item_tree_new             (GimpImage      *image,
+                                               GType           container_type,
+                                               GType           item_type);
+
+GimpItem     * gimp_item_tree_get_active_item (GimpItemTree   *tree);
+void           gimp_item_tree_set_active_item (GimpItemTree   *tree,
+                                               GimpItem       *item);
+
+GimpItem     * gimp_item_tree_get_insert_pos  (GimpItemTree   *tree,
+                                               GimpItem       *parent,
+                                               gint           *position,
+                                               GimpItem       *active_item);
+
+void           gimp_item_tree_add_item        (GimpItemTree *tree,
+                                               GimpItem     *item,
+                                               GimpItem     *parent,
+                                               gint          position);
+GimpItem     * gimp_item_tree_remove_item     (GimpItemTree *tree,
+                                               GimpItem     *item,
+                                               GimpItem     *current_active,
+                                               GimpItem     *new_active);
+
+gboolean       gimp_item_tree_reorder_item    (GimpItemTree *tree,
+                                               GimpItem     *item,
+                                               GimpItem     *new_parent,
+                                               gint          new_index,
+                                               gboolean      push_undo,
+                                               const gchar  *undo_desc);
+
 
 #endif  /*  __GIMP_ITEM_TREE_H__  */



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