[gimp] app: add a layer boundary canvas item class



commit 3e69ae00390aa97879bffcd5d628ad9710142049
Author: Michael Natterer <mitch gimp org>
Date:   Sun Oct 3 00:28:40 2010 +0200

    app: add a layer boundary canvas item class
    
    and use it to draw the layer boundary. Remove a lot of stuff
    that was there only to draw the boundary before:
    
    - remvoe all layer boundary stuff from the selection code
    - remove gimp_display_shell_draw_layer()
    - remove enum values GIMP_SELECTION_LAYER_ON,OFF from core-enums.h
    - remove all lines calling gimp_image_selection_control() with
      the removed enum values
    - remove gimp_layer_boundary()

 app/core/core-enums.c                     |    4 -
 app/core/core-enums.h                     |    2 -
 app/core/gimplayer.c                      |   73 -------
 app/core/gimplayer.h                      |    2 -
 app/core/gimplayermask.c                  |   11 +-
 app/display/Makefile.am                   |    2 +
 app/display/gimpcanvaslayerboundary.c     |  303 +++++++++++++++++++++++++++++
 app/display/gimpcanvaslayerboundary.h     |   58 ++++++
 app/display/gimpdisplayshell-appearance.c |    2 +-
 app/display/gimpdisplayshell-draw.c       |   18 --
 app/display/gimpdisplayshell-draw.h       |    5 -
 app/display/gimpdisplayshell-handlers.c   |    7 +
 app/display/gimpdisplayshell-items.c      |   15 +-
 app/display/gimpdisplayshell-selection.c  |  136 +-------------
 app/display/gimpdisplayshell-selection.h  |   14 +-
 app/display/gimpdisplayshell-style.c      |   10 +-
 app/display/gimpdisplayshell-style.h      |    2 +-
 app/display/gimpdisplayshell.c            |    4 +
 app/display/gimpdisplayshell.h            |    1 +
 19 files changed, 405 insertions(+), 264 deletions(-)
---
diff --git a/app/core/core-enums.c b/app/core/core-enums.c
index 88a23b1..2b271a1 100644
--- a/app/core/core-enums.c
+++ b/app/core/core-enums.c
@@ -644,8 +644,6 @@ gimp_selection_control_get_type (void)
   static const GEnumValue values[] =
   {
     { GIMP_SELECTION_OFF, "GIMP_SELECTION_OFF", "off" },
-    { GIMP_SELECTION_LAYER_OFF, "GIMP_SELECTION_LAYER_OFF", "layer-off" },
-    { GIMP_SELECTION_LAYER_ON, "GIMP_SELECTION_LAYER_ON", "layer-on" },
     { GIMP_SELECTION_ON, "GIMP_SELECTION_ON", "on" },
     { GIMP_SELECTION_PAUSE, "GIMP_SELECTION_PAUSE", "pause" },
     { GIMP_SELECTION_RESUME, "GIMP_SELECTION_RESUME", "resume" },
@@ -655,8 +653,6 @@ gimp_selection_control_get_type (void)
   static const GimpEnumDesc descs[] =
   {
     { GIMP_SELECTION_OFF, "GIMP_SELECTION_OFF", NULL },
-    { GIMP_SELECTION_LAYER_OFF, "GIMP_SELECTION_LAYER_OFF", NULL },
-    { GIMP_SELECTION_LAYER_ON, "GIMP_SELECTION_LAYER_ON", NULL },
     { GIMP_SELECTION_ON, "GIMP_SELECTION_ON", NULL },
     { GIMP_SELECTION_PAUSE, "GIMP_SELECTION_PAUSE", NULL },
     { GIMP_SELECTION_RESUME, "GIMP_SELECTION_RESUME", NULL },
diff --git a/app/core/core-enums.h b/app/core/core-enums.h
index 029eb66..6fa4cba 100644
--- a/app/core/core-enums.h
+++ b/app/core/core-enums.h
@@ -297,8 +297,6 @@ GType gimp_selection_control_get_type (void) G_GNUC_CONST;
 typedef enum  /*< pdb-skip >*/
 {
   GIMP_SELECTION_OFF,
-  GIMP_SELECTION_LAYER_OFF,
-  GIMP_SELECTION_LAYER_ON,
   GIMP_SELECTION_ON,
   GIMP_SELECTION_PAUSE,
   GIMP_SELECTION_RESUME
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index 5f9295e..3397d01 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -858,9 +858,6 @@ gimp_layer_invalidate_boundary (GimpDrawable *drawable)
   /*  Turn the current selection off  */
   gimp_image_selection_control (image, GIMP_SELECTION_OFF);
 
-  /*  clear the affected region surrounding the layer  */
-  gimp_image_selection_control (image, GIMP_SELECTION_LAYER_OFF);
-
   /*  get the selection mask channel  */
   mask = gimp_image_get_mask (image);
 
@@ -1918,76 +1915,6 @@ gimp_layer_resize_to_image (GimpLayer   *layer,
   gimp_image_undo_group_end (image);
 }
 
-BoundSeg *
-gimp_layer_boundary (GimpLayer *layer,
-                     gint      *num_segs)
-{
-  GimpItem *item;
-  BoundSeg *new_segs;
-  gint      offset_x;
-  gint      offset_y;
-
-  g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
-
-  if (gimp_layer_is_floating_sel (layer))
-    {
-      GimpDrawable *fs_drawable;
-
-      fs_drawable = gimp_layer_get_floating_sel_drawable (layer);
-
-      if (GIMP_IS_CHANNEL (fs_drawable))
-        {
-          /*  if the owner drawable is a channel, just return nothing  */
-
-          *num_segs = 0;
-
-          return NULL;
-        }
-      else
-        {
-          /*  otherwise, set the layer to the owner drawable  */
-
-          layer = GIMP_LAYER (fs_drawable);
-        }
-    }
-
-  item = GIMP_ITEM (layer);
-
-  /*  Create the four boundary segments that encompass this
-   *  layer's boundary.
-   */
-  new_segs  = g_new (BoundSeg, 4);
-  *num_segs = 4;
-
-  gimp_item_get_offset (item, &offset_x, &offset_y);
-
-  new_segs[0].x1   = offset_x;
-  new_segs[0].y1   = offset_y;
-  new_segs[0].x2   = offset_x;
-  new_segs[0].y2   = offset_y + gimp_item_get_height (item);
-  new_segs[0].open = 1;
-
-  new_segs[1].x1   = offset_x;
-  new_segs[1].y1   = offset_y;
-  new_segs[1].x2   = offset_x + gimp_item_get_width (item);
-  new_segs[1].y2   = offset_y;
-  new_segs[1].open = 1;
-
-  new_segs[2].x1   = offset_x + gimp_item_get_width (item);
-  new_segs[2].y1   = offset_y;
-  new_segs[2].x2   = offset_x + gimp_item_get_width  (item);
-  new_segs[2].y2   = offset_y + gimp_item_get_height (item);
-  new_segs[2].open = 0;
-
-  new_segs[3].x1   = offset_x;
-  new_segs[3].y1   = offset_y + gimp_item_get_height (item);
-  new_segs[3].x2   = offset_x + gimp_item_get_width  (item);
-  new_segs[3].y2   = offset_y + gimp_item_get_height (item);
-  new_segs[3].open = 0;
-
-  return new_segs;
-}
-
 /**********************/
 /*  access functions  */
 /**********************/
diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h
index 1ac2197..94307fc 100644
--- a/app/core/gimplayer.h
+++ b/app/core/gimplayer.h
@@ -116,8 +116,6 @@ void            gimp_layer_flatten             (GimpLayer            *layer,
 
 void            gimp_layer_resize_to_image     (GimpLayer            *layer,
                                                 GimpContext          *context);
-BoundSeg      * gimp_layer_boundary            (GimpLayer            *layer,
-                                                gint                 *num_segs);
 
 GimpDrawable * gimp_layer_get_floating_sel_drawable (const GimpLayer *layer);
 void           gimp_layer_set_floating_sel_drawable (GimpLayer       *layer,
diff --git a/app/core/gimplayermask.c b/app/core/gimplayermask.c
index 0a5f57c..a0f9a2a 100644
--- a/app/core/gimplayermask.c
+++ b/app/core/gimplayermask.c
@@ -55,8 +55,6 @@ static gboolean        gimp_layer_mask_rename            (GimpItem       *item,
                                                           const gchar    *undo_desc,
                                                           GError        **error);
 
-static void            gimp_layer_mask_real_edit_changed (GimpLayerMask  *layer_mask);
-
 
 G_DEFINE_TYPE (GimpLayerMask, gimp_layer_mask, GIMP_TYPE_CHANNEL)
 
@@ -100,7 +98,7 @@ gimp_layer_mask_class_init (GimpLayerMaskClass *klass)
 
   viewable_class->default_stock_id = "gimp-layer-mask";
 
-  klass->edit_changed           = gimp_layer_mask_real_edit_changed;
+  klass->edit_changed           = NULL;
 
   item_class->is_attached       = gimp_layer_mask_is_attached;
   item_class->is_content_locked = gimp_layer_mask_is_content_locked;
@@ -307,13 +305,6 @@ gimp_layer_mask_get_edit (const GimpLayerMask *layer_mask)
   return layer_mask->edit_mask;
 }
 
-static void
-gimp_layer_mask_real_edit_changed (GimpLayerMask *layer_mask)
-{
-  gimp_image_selection_control (gimp_item_get_image (GIMP_ITEM (layer_mask)),
-                                GIMP_SELECTION_LAYER_ON);
-}
-
 void
 gimp_layer_mask_set_show (GimpLayerMask *layer_mask,
                           gboolean       show,
diff --git a/app/display/Makefile.am b/app/display/Makefile.am
index ecac2b1..9652627 100644
--- a/app/display/Makefile.am
+++ b/app/display/Makefile.am
@@ -37,6 +37,8 @@ libappdisplay_a_sources = \
 	gimpcanvashandle.h			\
 	gimpcanvasitem.c			\
 	gimpcanvasitem.h			\
+	gimpcanvaslayerboundary.c		\
+	gimpcanvaslayerboundary.h		\
 	gimpcanvasline.c			\
 	gimpcanvasline.h			\
 	gimpcanvaspolygon.c			\
diff --git a/app/display/gimpcanvaslayerboundary.c b/app/display/gimpcanvaslayerboundary.c
new file mode 100644
index 0000000..931dbe2
--- /dev/null
+++ b/app/display/gimpcanvaslayerboundary.c
@@ -0,0 +1,303 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcanvaslayerboundary.c
+ * Copyright (C) 2010 Michael Natterer <mitch gimp org>
+ *
+ * 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 <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpmath/gimpmath.h"
+
+#include "display-types.h"
+
+#include "core/gimpchannel.h"
+#include "core/gimplayer.h"
+#include "core/gimplayer-floating-sel.h"
+#include "core/gimplayermask.h"
+
+#include "gimpcanvas.h"
+#include "gimpcanvaslayerboundary.h"
+#include "gimpdisplayshell.h"
+#include "gimpdisplayshell-style.h"
+#include "gimpdisplayshell-transform.h"
+
+
+enum
+{
+  PROP_0,
+  PROP_LAYER
+};
+
+
+typedef struct _GimpCanvasLayerBoundaryPrivate GimpCanvasLayerBoundaryPrivate;
+
+struct _GimpCanvasLayerBoundaryPrivate
+{
+  GimpLayer *layer;
+  gboolean   edit_mask;
+};
+
+#define GET_PRIVATE(layer_boundary) \
+        G_TYPE_INSTANCE_GET_PRIVATE (layer_boundary, \
+                                     GIMP_TYPE_CANVAS_LAYER_BOUNDARY, \
+                                     GimpCanvasLayerBoundaryPrivate)
+
+
+/*  local function prototypes  */
+
+static void        gimp_canvas_layer_boundary_set_property (GObject          *object,
+                                                            guint             property_id,
+                                                            const GValue     *value,
+                                                            GParamSpec       *pspec);
+static void        gimp_canvas_layer_boundary_get_property (GObject          *object,
+                                                            guint             property_id,
+                                                            GValue           *value,
+                                                            GParamSpec       *pspec);
+static void        gimp_canvas_layer_boundary_draw         (GimpCanvasItem   *item,
+                                                            GimpDisplayShell *shell,
+                                                            cairo_t          *cr);
+static GdkRegion * gimp_canvas_layer_boundary_get_extents  (GimpCanvasItem   *item,
+                                                            GimpDisplayShell *shell);
+static void        gimp_canvas_layer_boundary_stroke       (GimpCanvasItem   *item,
+                                                            GimpDisplayShell *shell,
+                                                            cairo_t          *cr);
+
+
+G_DEFINE_TYPE (GimpCanvasLayerBoundary, gimp_canvas_layer_boundary,
+               GIMP_TYPE_CANVAS_RECTANGLE)
+
+#define parent_class gimp_canvas_layer_boundary_parent_class
+
+
+static void
+gimp_canvas_layer_boundary_class_init (GimpCanvasLayerBoundaryClass *klass)
+{
+  GObjectClass        *object_class = G_OBJECT_CLASS (klass);
+  GimpCanvasItemClass *item_class   = GIMP_CANVAS_ITEM_CLASS (klass);
+
+  object_class->set_property = gimp_canvas_layer_boundary_set_property;
+  object_class->get_property = gimp_canvas_layer_boundary_get_property;
+
+  item_class->draw           = gimp_canvas_layer_boundary_draw;
+  item_class->get_extents    = gimp_canvas_layer_boundary_get_extents;
+  item_class->stroke         = gimp_canvas_layer_boundary_stroke;
+
+  g_object_class_install_property (object_class, PROP_LAYER,
+                                   g_param_spec_object ("layer", NULL, NULL,
+                                                        GIMP_TYPE_LAYER,
+                                                        GIMP_PARAM_READWRITE));
+
+  g_type_class_add_private (klass, sizeof (GimpCanvasLayerBoundaryPrivate));
+}
+
+static void
+gimp_canvas_layer_boundary_init (GimpCanvasLayerBoundary *layer_boundary)
+{
+}
+
+static void
+gimp_canvas_layer_boundary_set_property (GObject      *object,
+                                         guint         property_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+  GimpCanvasLayerBoundaryPrivate *private = GET_PRIVATE (object);
+
+  switch (property_id)
+    {
+    case PROP_LAYER:
+      private->layer = g_value_get_object (value); /* don't ref */
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_canvas_layer_boundary_get_property (GObject    *object,
+                                         guint       property_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+  GimpCanvasLayerBoundaryPrivate *private = GET_PRIVATE (object);
+
+  switch (property_id)
+    {
+    case PROP_LAYER:
+      g_value_set_object (value, private->layer);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gimp_canvas_layer_boundary_draw (GimpCanvasItem   *item,
+                                 GimpDisplayShell *shell,
+                                 cairo_t          *cr)
+{
+  GimpCanvasLayerBoundaryPrivate *private = GET_PRIVATE (item);
+
+  if (private->layer)
+    GIMP_CANVAS_ITEM_CLASS (parent_class)->draw (item, shell, cr);
+}
+
+static GdkRegion *
+gimp_canvas_layer_boundary_get_extents (GimpCanvasItem   *item,
+                                        GimpDisplayShell *shell)
+{
+  GimpCanvasLayerBoundaryPrivate *private = GET_PRIVATE (item);
+
+  if (private->layer)
+    return GIMP_CANVAS_ITEM_CLASS (parent_class)->get_extents (item, shell);
+
+  return NULL;
+}
+
+static void
+gimp_canvas_layer_boundary_stroke (GimpCanvasItem   *item,
+                                   GimpDisplayShell *shell,
+                                   cairo_t          *cr)
+{
+  GimpCanvasLayerBoundaryPrivate *private = GET_PRIVATE (item);
+
+  gimp_display_shell_set_layer_style (shell, cr, private->layer);
+
+  cairo_stroke (cr);
+}
+
+GimpCanvasItem *
+gimp_canvas_layer_boundary_new (GimpDisplayShell *shell)
+{
+  g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
+
+  return g_object_new (GIMP_TYPE_CANVAS_LAYER_BOUNDARY,
+                       "shell", shell,
+                       NULL);
+}
+
+void
+gimp_canvas_layer_boundary_set_layer (GimpCanvasLayerBoundary *boundary,
+                                      GimpLayer               *layer)
+{
+  GimpCanvasLayerBoundaryPrivate *private;
+
+  g_return_if_fail (GIMP_IS_CANVAS_LAYER_BOUNDARY (boundary));
+  g_return_if_fail (layer == NULL || GIMP_IS_LAYER (layer));
+
+  private = GET_PRIVATE (boundary);
+
+  if (layer && gimp_layer_is_floating_sel (layer))
+    {
+      GimpDrawable *drawable;
+
+      drawable = gimp_layer_get_floating_sel_drawable (layer);
+
+      if (GIMP_IS_CHANNEL (drawable))
+        {
+          /*  if the owner drawable is a channel, show no outline  */
+
+          layer = NULL;
+        }
+      else
+        {
+          /*  otherwise, set the layer to the owner drawable  */
+
+          layer = GIMP_LAYER (drawable);
+        }
+    }
+
+  if (layer != private->layer)
+    {
+      gimp_canvas_item_begin_change (GIMP_CANVAS_ITEM (boundary));
+
+      g_object_set (boundary, "layer", layer, NULL);
+
+      if (layer)
+        {
+          GimpItem      *item = GIMP_ITEM (layer);
+          GimpLayerMask *mask;
+
+          g_object_set (boundary,
+                        "x",      (gdouble) gimp_item_get_offset_x (item),
+                        "y",      (gdouble) gimp_item_get_offset_y (item),
+                        "width",  (gdouble) gimp_item_get_width  (item),
+                        "height", (gdouble) gimp_item_get_height (item),
+                        NULL);
+
+          mask = gimp_layer_get_mask (layer);
+          private->edit_mask = (mask && gimp_layer_mask_get_edit (mask));
+        }
+      else
+        {
+          private->edit_mask = FALSE;
+        }
+
+      gimp_canvas_item_end_change (GIMP_CANVAS_ITEM (boundary));
+    }
+  else if (layer && layer == private->layer)
+    {
+      GimpItem      *item = GIMP_ITEM (layer);
+      GimpLayerMask *mask;
+      gint           lx, ly, lw, lh;
+      gdouble        x, y, w ,h;
+      gboolean       edit_mask;
+
+      lx = gimp_item_get_offset_x (item);
+      ly = gimp_item_get_offset_y (item);
+      lw = gimp_item_get_width  (item);
+      lh = gimp_item_get_height (item);
+
+      mask = gimp_layer_get_mask (layer);
+      edit_mask = (mask && gimp_layer_mask_get_edit (mask));
+
+      g_object_get (boundary,
+                    "x",      &x,
+                    "y",      &y,
+                    "width",  &w,
+                    "height", &h,
+                    NULL);
+
+      if (lx        != (gint) x ||
+          ly        != (gint) y ||
+          lw        != (gint) w ||
+          lh        != (gint) h ||
+          edit_mask != private->edit_mask)
+        {
+          gimp_canvas_item_begin_change (GIMP_CANVAS_ITEM (boundary));
+
+          g_object_set (boundary,
+                        "x",      (gdouble) lx,
+                        "y",      (gdouble) ly,
+                        "width",  (gdouble) lw,
+                        "height", (gdouble) lh,
+                        NULL);
+
+          private->edit_mask = edit_mask;
+
+          gimp_canvas_item_end_change (GIMP_CANVAS_ITEM (boundary));
+        }
+    }
+}
diff --git a/app/display/gimpcanvaslayerboundary.h b/app/display/gimpcanvaslayerboundary.h
new file mode 100644
index 0000000..d9420fc
--- /dev/null
+++ b/app/display/gimpcanvaslayerboundary.h
@@ -0,0 +1,58 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcanvaslayerboundary.h
+ * Copyright (C) 2010 Michael Natterer <mitch gimp org>
+ *
+ * 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_CANVAS_LAYER_BOUNDARY_H__
+#define __GIMP_CANVAS_LAYER_BOUNDARY_H__
+
+
+#include "gimpcanvasrectangle.h"
+
+
+#define GIMP_TYPE_CANVAS_LAYER_BOUNDARY            (gimp_canvas_layer_boundary_get_type ())
+#define GIMP_CANVAS_LAYER_BOUNDARY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CANVAS_LAYER_BOUNDARY, GimpCanvasLayerBoundary))
+#define GIMP_CANVAS_LAYER_BOUNDARY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CANVAS_LAYER_BOUNDARY, GimpCanvasLayerBoundaryClass))
+#define GIMP_IS_CANVAS_LAYER_BOUNDARY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CANVAS_LAYER_BOUNDARY))
+#define GIMP_IS_CANVAS_LAYER_BOUNDARY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CANVAS_LAYER_BOUNDARY))
+#define GIMP_CANVAS_LAYER_BOUNDARY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CANVAS_LAYER_BOUNDARY, GimpCanvasLayerBoundaryClass))
+
+
+typedef struct _GimpCanvasLayerBoundary      GimpCanvasLayerBoundary;
+typedef struct _GimpCanvasLayerBoundaryClass GimpCanvasLayerBoundaryClass;
+
+struct _GimpCanvasLayerBoundary
+{
+  GimpCanvasRectangle  parent_instance;
+};
+
+struct _GimpCanvasLayerBoundaryClass
+{
+  GimpCanvasRectangleClass  parent_class;
+};
+
+
+GType            gimp_canvas_layer_boundary_get_type  (void) G_GNUC_CONST;
+
+GimpCanvasItem * gimp_canvas_layer_boundary_new       (GimpDisplayShell        *shell);
+
+void             gimp_canvas_layer_boundary_set_layer (GimpCanvasLayerBoundary *boundary,
+                                                       GimpLayer               *layer);
+
+
+#endif /* __GIMP_CANVAS_LAYER_BOUNDARY_H__ */
diff --git a/app/display/gimpdisplayshell-appearance.c b/app/display/gimpdisplayshell-appearance.c
index b251c9a..2e2ef77 100644
--- a/app/display/gimpdisplayshell-appearance.c
+++ b/app/display/gimpdisplayshell-appearance.c
@@ -257,7 +257,7 @@ gimp_display_shell_set_show_layer (GimpDisplayShell *shell,
 
   g_object_set (options, "show-layer-boundary", show, NULL);
 
-  gimp_display_shell_selection_set_layer_hidden (shell, ! show);
+  gimp_canvas_item_set_visible (shell->layer_boundary, show);
 
   appearance_set_action_active (shell, "view-show-layer-boundary", show);
 }
diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c
index 3053b5f..107d0e8 100644
--- a/app/display/gimpdisplayshell-draw.c
+++ b/app/display/gimpdisplayshell-draw.c
@@ -163,24 +163,6 @@ gimp_display_shell_draw_pen (GimpDisplayShell  *shell,
 }
 
 void
-gimp_display_shell_draw_layer_boundary (GimpDisplayShell *shell,
-                                        cairo_t          *cr,
-                                        GimpDrawable     *drawable,
-                                        GdkSegment       *segs,
-                                        gint              n_segs)
-{
-  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
-  g_return_if_fail (cr != NULL);
-  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
-  g_return_if_fail (segs != NULL && n_segs == 4);
-
-  gimp_display_shell_set_layer_style (shell, cr, drawable);
-
-  gimp_cairo_add_segments (cr, segs, n_segs);
-  cairo_stroke (cr);
-}
-
-void
 gimp_display_shell_draw_selection_out (GimpDisplayShell *shell,
                                        cairo_t          *cr,
                                        GdkSegment       *segs,
diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h
index e328b79..ef43e94 100644
--- a/app/display/gimpdisplayshell-draw.h
+++ b/app/display/gimpdisplayshell-draw.h
@@ -35,11 +35,6 @@ void   gimp_display_shell_draw_pen                   (GimpDisplayShell   *shell,
                                                       GimpContext        *context,
                                                       GimpActiveColor     color,
                                                       gint                width);
-void   gimp_display_shell_draw_layer_boundary        (GimpDisplayShell   *shell,
-                                                      cairo_t            *cr,
-                                                      GimpDrawable       *drawable,
-                                                      GdkSegment         *segs,
-                                                      gint                n_segs);
 void   gimp_display_shell_draw_selection_out         (GimpDisplayShell   *shell,
                                                       cairo_t            *cr,
                                                       GdkSegment         *segs,
diff --git a/app/display/gimpdisplayshell-handlers.c b/app/display/gimpdisplayshell-handlers.c
index 92b94f4..0bebde5 100644
--- a/app/display/gimpdisplayshell-handlers.c
+++ b/app/display/gimpdisplayshell-handlers.c
@@ -46,6 +46,7 @@
 #include "widgets/gimpwidgets-utils.h"
 
 #include "gimpcanvasguide.h"
+#include "gimpcanvaslayerboundary.h"
 #include "gimpcanvasproxygroup.h"
 #include "gimpcanvassamplepoint.h"
 #include "gimpdisplay.h"
@@ -312,6 +313,9 @@ gimp_display_shell_connect (GimpDisplayShell *shell)
 
   gimp_display_shell_invalidate_preview_handler (image, shell);
   gimp_display_shell_quick_mask_changed_handler (image, shell);
+
+  gimp_canvas_layer_boundary_set_layer (GIMP_CANVAS_LAYER_BOUNDARY (shell->layer_boundary),
+                                        gimp_image_get_active_layer (image));
 }
 
 void
@@ -329,6 +333,9 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
 
   gimp_display_shell_icon_update_stop (shell);
 
+  gimp_canvas_layer_boundary_set_layer (GIMP_CANVAS_LAYER_BOUNDARY (shell->layer_boundary),
+                                        NULL);
+
   g_signal_handlers_disconnect_by_func (shell->display->config,
                                         gimp_display_shell_quality_notify_handler,
                                         shell);
diff --git a/app/display/gimpdisplayshell-items.c b/app/display/gimpdisplayshell-items.c
index 15d5041..c1dd252 100644
--- a/app/display/gimpdisplayshell-items.c
+++ b/app/display/gimpdisplayshell-items.c
@@ -26,6 +26,7 @@
 
 #include "gimpcanvascursor.h"
 #include "gimpcanvasgrid.h"
+#include "gimpcanvaslayerboundary.h"
 #include "gimpcanvasproxygroup.h"
 #include "gimpdisplayshell.h"
 #include "gimpdisplayshell-expose.h"
@@ -61,6 +62,11 @@ gimp_display_shell_items_init (GimpDisplayShell *shell)
   gimp_display_shell_add_item (shell, shell->sample_points);
   g_object_unref (shell->sample_points);
 
+  shell->layer_boundary = gimp_canvas_layer_boundary_new (shell);
+  gimp_canvas_item_set_visible (shell->layer_boundary, FALSE);
+  gimp_display_shell_add_item (shell, shell->layer_boundary);
+  g_object_unref (shell->layer_boundary);
+
   shell->cursor = gimp_canvas_cursor_new (shell);
   gimp_canvas_item_set_visible (shell->cursor, FALSE);
   gimp_display_shell_add_item (shell, shell->cursor);
@@ -85,10 +91,11 @@ gimp_display_shell_items_free (GimpDisplayShell *shell)
       g_object_unref (shell->canvas_item);
       shell->canvas_item = NULL;
 
-      shell->grid          = NULL;
-      shell->guides        = NULL;
-      shell->sample_points = NULL;
-      shell->cursor        = NULL;
+      shell->grid           = NULL;
+      shell->guides         = NULL;
+      shell->sample_points  = NULL;
+      shell->layer_boundary = NULL;
+      shell->cursor         = NULL;
     }
 }
 
diff --git a/app/display/gimpdisplayshell-selection.c b/app/display/gimpdisplayshell-selection.c
index 936fbcf..c7779f7 100644
--- a/app/display/gimpdisplayshell-selection.c
+++ b/app/display/gimpdisplayshell-selection.c
@@ -27,8 +27,7 @@
 #include "base/boundary.h"
 
 #include "core/gimp.h"
-#include "core/gimplayer.h"
-#include "core/gimplayermask.h"
+#include "core/gimpchannel.h"
 #include "core/gimpimage.h"
 
 #include "widgets/gimpcairo.h"
@@ -52,14 +51,10 @@ struct _Selection
   GdkSegment       *segs_out;         /*  gdk segments of area boundary     */
   gint              n_segs_out;       /*  number of segments in segs_out    */
 
-  GdkSegment       *segs_layer;       /*  segments of layer boundary        */
-  gint              n_segs_layer;     /*  number of segments in segs_layer  */
-
   guint             index;            /*  index of current stipple pattern  */
   gint              paused;           /*  count of pause requests           */
   gboolean          visible;          /*  visility of the display shell     */
   gboolean          hidden;           /*  is the selection hidden?          */
-  gboolean          layer_hidden;     /*  is the layer boundary hidden?     */
   guint             timeout;          /*  timer for successive draws        */
   cairo_pattern_t  *segs_in_mask;     /*  cache for rendered segments       */
 };
@@ -75,8 +70,6 @@ static void      selection_resume         (Selection      *selection);
 
 static void      selection_draw           (Selection      *selection);
 static void      selection_undraw         (Selection      *selection);
-static void      selection_layer_undraw   (Selection      *selection);
-static void      selection_layer_draw     (Selection      *selection);
 
 static void      selection_render_mask    (Selection      *selection);
 
@@ -110,10 +103,9 @@ gimp_display_shell_selection_init (GimpDisplayShell *shell)
 
   selection = g_slice_new0 (Selection);
 
-  selection->shell        = shell;
-  selection->visible      = TRUE;
-  selection->hidden       = ! gimp_display_shell_get_show_selection (shell);
-  selection->layer_hidden = ! gimp_display_shell_get_show_layer (shell);
+  selection->shell   = shell;
+  selection->visible = TRUE;
+  selection->hidden  = ! gimp_display_shell_get_show_selection (shell);
 
   shell->selection = selection;
 
@@ -167,15 +159,6 @@ gimp_display_shell_selection_control (GimpDisplayShell     *shell,
           selection_undraw (selection);
           break;
 
-        case GIMP_SELECTION_LAYER_OFF:
-          selection_layer_undraw (selection);
-          break;
-
-        case GIMP_SELECTION_LAYER_ON:
-          if (! selection->layer_hidden)
-            selection_layer_draw (selection);
-          break;
-
         case GIMP_SELECTION_ON:
           selection_start (selection);
           break;
@@ -209,7 +192,6 @@ gimp_display_shell_selection_set_hidden (GimpDisplayShell *shell,
       if (hidden != selection->hidden)
         {
           selection_undraw (selection);
-          selection_layer_undraw (selection);
 
           selection->hidden = hidden;
 
@@ -218,28 +200,6 @@ gimp_display_shell_selection_set_hidden (GimpDisplayShell *shell,
     }
 }
 
-void
-gimp_display_shell_selection_set_layer_hidden (GimpDisplayShell *shell,
-                                               gboolean          hidden)
-{
-  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
-
-  if (shell->selection && gimp_display_get_image (shell->display))
-    {
-      Selection *selection = shell->selection;
-
-      if (hidden != selection->layer_hidden)
-        {
-          selection_undraw (selection);
-          selection_layer_undraw (selection);
-
-          selection->layer_hidden = hidden;
-
-          selection_start (selection);
-        }
-    }
-}
-
 
 /*  private functions  */
 
@@ -321,62 +281,6 @@ selection_undraw (Selection *selection)
 }
 
 static void
-selection_layer_draw (Selection *selection)
-{
-  if (selection->segs_layer)
-    {
-      GimpImage    *image;
-      GimpDrawable *drawable;
-      cairo_t      *cr;
-
-      image    = gimp_display_get_image (selection->shell->display);
-      drawable = gimp_image_get_active_drawable (image);
-
-      cr = gdk_cairo_create (gtk_widget_get_window (selection->shell->canvas));
-
-      gimp_display_shell_draw_layer_boundary (selection->shell, cr,
-                                              drawable,
-                                              selection->segs_layer,
-                                              selection->n_segs_layer);
-
-      cairo_destroy (cr);
-    }
-}
-
-static void
-selection_layer_undraw (Selection *selection)
-{
-  selection_stop (selection);
-
-  if (selection->segs_layer && selection->n_segs_layer == 4)
-    {
-      const gint x1 = selection->segs_layer[0].x1 - 1;
-      const gint y1 = selection->segs_layer[0].y1 - 1;
-      const gint x2 = selection->segs_layer[3].x2 + 1;
-      const gint y2 = selection->segs_layer[3].y2 + 1;
-
-      const gint x3 = selection->segs_layer[0].x1 + 1;
-      const gint y3 = selection->segs_layer[0].y1 + 1;
-      const gint x4 = selection->segs_layer[3].x2 - 1;
-      const gint y4 = selection->segs_layer[3].y2 - 1;
-
-      /*  expose the region, this will restart the selection  */
-      gimp_display_shell_expose_area (selection->shell,
-                                      x1, y1, (x2 - x1) + 1, (y3 - y1) + 1);
-      gimp_display_shell_expose_area (selection->shell,
-                                      x1, y3, (x3 - x1) + 1, (y4 - y3) + 1);
-      gimp_display_shell_expose_area (selection->shell,
-                                      x1, y4, (x2 - x1) + 1, (y2 - y4) + 1);
-      gimp_display_shell_expose_area (selection->shell,
-                                      x4, y3, (x2 - x4) + 1, (y4 - y3) + 1);
-    }
-  else
-    {
-      selection_start (selection);
-    }
-}
-
-static void
 selection_render_mask (Selection *selection)
 {
   cairo_t *cr;
@@ -448,7 +352,6 @@ selection_generate_segs (Selection *selection)
   GimpImage      *image = gimp_display_get_image (selection->shell->display);
   const BoundSeg *segs_in;
   const BoundSeg *segs_out;
-  GimpLayer      *layer;
 
   /*  Ask the image for the boundary of its selected region...
    *  Then transform that information into a new buffer of GdkSegments
@@ -482,27 +385,6 @@ selection_generate_segs (Selection *selection)
     {
       selection->segs_out = NULL;
     }
-
-  layer = gimp_image_get_active_layer (image);
-
-  if (layer)
-    {
-      BoundSeg *segs;
-
-      segs = gimp_layer_boundary (layer, &selection->n_segs_layer);
-
-      if (selection->n_segs_layer)
-        {
-          selection->segs_layer = g_new (GdkSegment, selection->n_segs_layer);
-
-          selection_transform_segs (selection,
-                                    segs,
-                                    selection->segs_layer,
-                                    selection->n_segs_layer);
-        }
-
-      g_free (segs);
-    }
 }
 
 static void
@@ -522,13 +404,6 @@ selection_free_segs (Selection *selection)
       selection->n_segs_out = 0;
     }
 
-  if (selection->segs_layer)
-    {
-      g_free (selection->segs_layer);
-      selection->segs_layer   = NULL;
-      selection->n_segs_layer = 0;
-    }
-
   if (selection->segs_in_mask)
     {
       cairo_pattern_destroy (selection->segs_in_mask);
@@ -549,9 +424,6 @@ selection_start_timeout (Selection *selection)
 
   selection->index = 0;
 
-  if (! selection->layer_hidden)
-    selection_layer_draw (selection);
-
   /*  Draw the ants  */
   if (! selection->hidden)
     {
diff --git a/app/display/gimpdisplayshell-selection.h b/app/display/gimpdisplayshell-selection.h
index 10bb1d1..3289eb0 100644
--- a/app/display/gimpdisplayshell-selection.h
+++ b/app/display/gimpdisplayshell-selection.h
@@ -19,16 +19,14 @@
 #define __GIMP_DISPLAY_SHELL_SELECTION_H__
 
 
-void   gimp_display_shell_selection_init     (GimpDisplayShell     *shell);
-void   gimp_display_shell_selection_free     (GimpDisplayShell     *shell);
+void   gimp_display_shell_selection_init       (GimpDisplayShell     *shell);
+void   gimp_display_shell_selection_free       (GimpDisplayShell     *shell);
 
-void   gimp_display_shell_selection_control  (GimpDisplayShell     *shell,
-                                              GimpSelectionControl  control);
+void   gimp_display_shell_selection_control    (GimpDisplayShell     *shell,
+                                                GimpSelectionControl  control);
 
-void   gimp_display_shell_selection_set_hidden       (GimpDisplayShell *shell,
-                                                      gboolean          hidden);
-void   gimp_display_shell_selection_set_layer_hidden (GimpDisplayShell *shell,
-                                                      gboolean          hidden);
+void   gimp_display_shell_selection_set_hidden (GimpDisplayShell     *shell,
+                                                gboolean              hidden);
 
 
 #endif  /*  __GIMP_DISPLAY_SHELL_SELECTION_H__  */
diff --git a/app/display/gimpdisplayshell-style.c b/app/display/gimpdisplayshell-style.c
index 51753c1..4983fc8 100644
--- a/app/display/gimpdisplayshell-style.c
+++ b/app/display/gimpdisplayshell-style.c
@@ -30,6 +30,7 @@
 
 #include "core/gimpcontext.h"
 #include "core/gimpgrid.h"
+#include "core/gimplayer.h"
 #include "core/gimplayermask.h"
 
 #include "widgets/gimpcairo.h"
@@ -205,24 +206,25 @@ gimp_display_shell_set_pen_style (GimpDisplayShell *shell,
 void
 gimp_display_shell_set_layer_style (GimpDisplayShell *shell,
                                     cairo_t          *cr,
-                                    GimpDrawable     *drawable)
+                                    GimpLayer        *layer)
 {
   cairo_pattern_t *pattern;
 
   g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
   g_return_if_fail (cr != NULL);
-  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (GIMP_IS_LAYER (layer));
 
   cairo_set_line_width (cr, 1.0);
   cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
 
-  if (GIMP_IS_LAYER_MASK (drawable))
+  if (gimp_layer_get_mask (layer) &&
+      gimp_layer_mask_get_edit (gimp_layer_get_mask (layer)))
     {
       pattern = gimp_cairo_stipple_pattern_create (&layer_mask_fg,
                                                    &layer_mask_bg,
                                                    0);
     }
-  else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
+  else if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
     {
       pattern = gimp_cairo_stipple_pattern_create (&layer_group_fg,
                                                    &layer_group_bg,
diff --git a/app/display/gimpdisplayshell-style.h b/app/display/gimpdisplayshell-style.h
index c24d5b5..1b6431f 100644
--- a/app/display/gimpdisplayshell-style.h
+++ b/app/display/gimpdisplayshell-style.h
@@ -38,7 +38,7 @@ void   gimp_display_shell_set_pen_style           (GimpDisplayShell *shell,
                                                    gint              width);
 void   gimp_display_shell_set_layer_style         (GimpDisplayShell *shell,
                                                    cairo_t          *cr,
-                                                   GimpDrawable     *drawable);
+                                                   GimpLayer        *layer);
 void   gimp_display_shell_set_selection_out_style (GimpDisplayShell *shell,
                                                    cairo_t          *cr);
 void   gimp_display_shell_set_selection_in_style  (GimpDisplayShell *shell,
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index ab920f8..435bbc1 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -53,6 +53,7 @@
 #include "tools/tool_manager.h"
 
 #include "gimpcanvas.h"
+#include "gimpcanvaslayerboundary.h"
 #include "gimpdisplay.h"
 #include "gimpdisplayshell.h"
 #include "gimpdisplayshell-appearance.h"
@@ -1660,6 +1661,9 @@ gimp_display_shell_flush (GimpDisplayShell *shell,
   /* make sure the information is up-to-date */
   gimp_display_shell_scale_changed (shell);
 
+  gimp_canvas_layer_boundary_set_layer (GIMP_CANVAS_LAYER_BOUNDARY (shell->layer_boundary),
+                                        gimp_image_get_active_layer (gimp_display_get_image (shell->display)));
+
   if (now)
     {
       gdk_window_process_updates (gtk_widget_get_window (shell->canvas),
diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h
index 7edab21..a281339 100644
--- a/app/display/gimpdisplayshell.h
+++ b/app/display/gimpdisplayshell.h
@@ -139,6 +139,7 @@ struct _GimpDisplayShell
   GimpCanvasItem    *grid;             /*  item proxy of the grid             */
   GimpCanvasItem    *guides;           /*  item proxies of guides             */
   GimpCanvasItem    *sample_points;    /*  item proxies of sample points      */
+  GimpCanvasItem    *layer_boundary;   /*  item for the layer boundary        */
   GimpCanvasItem    *cursor;           /*  item for the software cursor       */
 
   guint              title_idle_id;    /*  title update idle ID               */



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